Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: im.counters returns null for unread msgs for user who never opened the DM #34109

Merged
merged 9 commits into from
Dec 6, 2024
5 changes: 5 additions & 0 deletions .changeset/proud-cups-share.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

Fixes `im.counters` endpoint returning `null` on `unread` messages property for users that have never opened the queried DM
4 changes: 2 additions & 2 deletions apps/meteor/app/api/server/v1/im.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,9 @@ API.v1.addRoute(

lm = room?.lm ? new Date(room.lm).toISOString() : new Date(room._updatedAt).toISOString(); // lm is the last message timestamp

if (subscription?.open) {
if (subscription) {
unreads = subscription.unread ?? null;
if (subscription.ls && room.msgs) {
unreads = subscription.unread;
unreadsFrom = new Date(subscription.ls).toISOString(); // last read timestamp
}
userMentions = subscription.userMentions;
Expand Down
131 changes: 111 additions & 20 deletions apps/meteor/tests/end-to-end/api/direct-message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,26 +343,117 @@ describe('[Direct Messages]', () => {
.end(done);
});

it('/im.counters', (done) => {
void request
.get(api('im.counters'))
.set(credentials)
.query({
roomId: directMessage._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('joined', true);
expect(res.body).to.have.property('members');
expect(res.body).to.have.property('unreads');
expect(res.body).to.have.property('unreadsFrom');
expect(res.body).to.have.property('msgs');
expect(res.body).to.have.property('latest');
expect(res.body).to.have.property('userMentions');
})
.end(done);
describe('/im.counters', () => {
it('should require auth', async () => {
await request
.get(api('im.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('im.counters'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
});
});
it('should work with all params right', (done) => {
void request
.get(api('im.counters'))
.set(credentials)
.query({
roomId: directMessage._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('joined', true);
expect(res.body).to.have.property('members');
expect(res.body).to.have.property('unreads');
expect(res.body).to.have.property('unreadsFrom');
expect(res.body).to.have.property('msgs');
expect(res.body).to.have.property('latest');
expect(res.body).to.have.property('userMentions');
})
.end(done);
});

describe('with valid room id', () => {
let testDM: IRoom & { rid: IRoom['_id'] };
let user2: TestUser<IUser>;
let userCreds: Credentials;

before(async () => {
user2 = await createUser();
userCreds = await login(user2.username, password);
await request
.post(api('im.create'))
.set(credentials)
.send({
username: user2.username,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
testDM = res.body.room;
});

await request
.post(api('chat.sendMessage'))
.set(credentials)
.send({
message: {
text: 'Sample message',
rid: testDM._id,
},
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
});

after(async () => {
await request
.post(api('im.delete'))
.set(credentials)
.send({
roomId: testDM._id,
})
.expect(200);

await deleteUser(user2);
});

it('should properly return counters before opening the dm', async () => {
await request
.get(api('im.counters'))
.set(userCreds)
.query({
roomId: testDM._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('joined', true);
expect(res.body).to.have.property('members').and.to.be.a('number').and.to.be.eq(2);
expect(res.body).to.have.property('unreads').and.to.be.a('number').and.to.be.eq(1);
expect(res.body).to.have.property('unreadsFrom');
expect(res.body).to.have.property('msgs').and.to.be.a('number').and.to.be.eq(1);
expect(res.body).to.have.property('latest');
expect(res.body).to.have.property('userMentions').and.to.be.a('number').and.to.be.eq(0);
});
});
});
});

describe('[/im.files]', async () => {
Expand Down
Loading