From d143ef0b7d3fe619dd58b5a5d488ca76ba6f760f Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 6 Jul 2022 22:05:00 +0530 Subject: [PATCH] feat: handle delete events accurately --- src/Tests/test.event-buffer.ts | 62 +++++++++++++++++++++++++++------- src/Utils/event-buffer.ts | 17 +++++++--- 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/src/Tests/test.event-buffer.ts b/src/Tests/test.event-buffer.ts index 41acef9..5e088cd 100644 --- a/src/Tests/test.event-buffer.ts +++ b/src/Tests/test.event-buffer.ts @@ -1,22 +1,23 @@ -import EventEmitter from 'events' import { proto } from '../../WAProto' -import { BaileysEventEmitter, Chat, WAMessageKey, WAMessageStatus, WAMessageStubType, WAMessageUpdate } from '../Types' +import { Chat, WAMessageKey, WAMessageStatus, WAMessageStubType, WAMessageUpdate } from '../Types' import { delay, generateMessageID, makeEventBuffer, toNumber, unixTimestampSeconds } from '../Utils' import logger from '../Utils/logger' import { randomJid } from './utils' describe('Event Buffer Tests', () => { - const emitter = new EventEmitter() as BaileysEventEmitter - const ev = makeEventBuffer(emitter, logger) + let ev: ReturnType + beforeEach(() => { + ev = makeEventBuffer(logger) + }) it('should buffer a chat upsert & update event', async() => { const chatId = randomJid() const chats: Chat[] = [] - emitter.on('chats.upsert', c => chats.push(...c)) - emitter.on('chats.update', () => fail('should not emit update event')) + ev.on('chats.upsert', c => chats.push(...c)) + ev.on('chats.update', () => fail('should not emit update event')) ev.buffer() ev.processInBuffer((async() => { @@ -35,6 +36,41 @@ describe('Event Buffer Tests', () => { expect(chats[0].unreadCount).toEqual(2) }) + it('should overwrite a chats.delete event', async() => { + const chatId = randomJid() + const chats: Partial[] = [] + + ev.on('chats.update', c => chats.push(...c)) + ev.on('chats.delete', () => fail('not should have emitted')) + + ev.buffer() + + ev.emit('chats.update', [{ id: chatId, conversationTimestamp: 123, unreadCount: 1 }]) + ev.emit('chats.delete', [chatId]) + ev.emit('chats.update', [{ id: chatId, conversationTimestamp: 124, unreadCount: 1 }]) + + await ev.flush() + + expect(chats).toHaveLength(1) + }) + + it('should overwrite a chats.update event', async() => { + const chatId = randomJid() + const chatsDeleted: string[] = [] + + ev.on('chats.delete', c => chatsDeleted.push(...c)) + ev.on('chats.update', () => fail('not should have emitted')) + + ev.buffer() + + ev.emit('chats.update', [{ id: chatId, conversationTimestamp: 123, unreadCount: 1 }]) + ev.emit('chats.delete', [chatId]) + + await ev.flush() + + expect(chatsDeleted).toHaveLength(1) + }) + it('should buffer message upsert events', async() => { const messageTimestamp = unixTimestampSeconds() const msg: proto.IWebMessageInfo = { @@ -49,7 +85,7 @@ describe('Event Buffer Tests', () => { const msgs: proto.IWebMessageInfo[] = [] - emitter.on('messages.upsert', c => { + ev.on('messages.upsert', c => { msgs.push(...c.messages) expect(c.type).toEqual('notify') }) @@ -67,7 +103,7 @@ describe('Event Buffer Tests', () => { expect(msgs).toHaveLength(1) expect(msgs[0].message).toBeTruthy() - expect(toNumber(msgs[0].messageTimestamp)).toEqual(messageTimestamp) + expect(toNumber(msgs[0].messageTimestamp!)).toEqual(messageTimestamp) expect(msgs[0].status).toEqual(WAMessageStatus.READ) }) @@ -84,8 +120,8 @@ describe('Event Buffer Tests', () => { const msgs: proto.IWebMessageInfo[] = [] - emitter.on('messages.upsert', c => msgs.push(...c.messages)) - emitter.on('message-receipt.update', () => fail('should not emit')) + ev.on('messages.upsert', c => msgs.push(...c.messages)) + ev.on('message-receipt.update', () => fail('should not emit')) ev.buffer() ev.emit('messages.upsert', { messages: [proto.WebMessageInfo.fromObject(msg)], type: 'notify' }) @@ -114,7 +150,7 @@ describe('Event Buffer Tests', () => { const msgs: WAMessageUpdate[] = [] - emitter.on('messages.update', c => msgs.push(...c)) + ev.on('messages.update', c => msgs.push(...c)) ev.buffer() ev.emit('messages.update', [{ key, update: { status: WAMessageStatus.DELIVERY_ACK } }]) @@ -141,11 +177,11 @@ describe('Event Buffer Tests', () => { const chats: Partial[] = [] - emitter.on('chats.update', c => chats.push(...c)) + ev.on('chats.update', c => chats.push(...c)) ev.buffer() ev.emit('messages.upsert', { messages: [proto.WebMessageInfo.fromObject(msg)], type: 'notify' }) - ev.emit('chats.update', [{ id: msg.key.remoteJid, unreadCount: 1, conversationTimestamp: msg.messageTimestamp }]) + ev.emit('chats.update', [{ id: msg.key.remoteJid!, unreadCount: 1, conversationTimestamp: msg.messageTimestamp }]) ev.emit('messages.update', [{ key: msg.key, update: { status: WAMessageStatus.READ } }]) await ev.flush() diff --git a/src/Utils/event-buffer.ts b/src/Utils/event-buffer.ts index 96c7565..2875513 100644 --- a/src/Utils/event-buffer.ts +++ b/src/Utils/event-buffer.ts @@ -150,18 +150,27 @@ function append( delete data.chatUpdates[chat.id] } + if(data.chatDeletes.has(chat.id)) { + data.chatDeletes.delete(chat.id) + } + data.chatUpserts[chat.id] = upsert } break case 'chats.update': for(const update of eventData as Partial[]) { - const upsert = data.chatUpserts[update.id!] + const chatId = update.id! + const upsert = data.chatUpserts[chatId] if(upsert) { concatChats(upsert, update) } else { - const chatUpdate = data.chatUpdates[update.id] || { } - data.chatUpdates[update.id] = concatChats(chatUpdate, update) + const chatUpdate = data.chatUpdates[chatId] || { } + data.chatUpdates[chatId] = concatChats(chatUpdate, update) + } + + if(data.chatDeletes.has(chatId)) { + data.chatDeletes.delete(chatId) } } @@ -315,7 +324,7 @@ function append( if( isRealMessage(message) && shouldIncrementChatUnread(message) - && typeof chat.unreadCount !== 'undefined' + && typeof chat?.unreadCount !== 'undefined' && chat.unreadCount > 0 ) { logger.debug({ chatId: chat.id }, 'decrementing chat counter')