Duplicate message after reconnect fix

This commit is contained in:
Adhiraj Singh
2020-12-09 00:01:37 +05:30
parent caf82a46a8
commit 376a43f116
5 changed files with 31 additions and 15 deletions

View File

@@ -54,6 +54,8 @@ export const WAConnectionTest = (name: string, func: (conn: WAConnection) => voi
await fs.writeFile(file, JSON.stringify(conn.base64EncodedAuthInfo(), null, '\t')) await fs.writeFile(file, JSON.stringify(conn.base64EncodedAuthInfo(), null, '\t'))
}) })
after(() => conn.close()) after(() => conn.close())
afterEach (() => assertChatDBIntegrity (conn))
func(conn) func(conn)
}) })

View File

@@ -23,7 +23,7 @@ WAConnectionTest('Groups', (conn) => {
it('should retreive group metadata', async () => { it('should retreive group metadata', async () => {
const metadata = await conn.groupMetadata(gid) const metadata = await conn.groupMetadata(gid)
assert.strictEqual(metadata.id, gid) assert.strictEqual(metadata.id, gid)
assert.strictEqual(metadata.participants.filter((obj) => obj.id.split('@')[0] === testJid.split('@')[0]).length, 1) assert.strictEqual(metadata.participants.filter((obj) => obj.jid.split('@')[0] === testJid.split('@')[0]).length, 1)
assert.ok(conn.chats.get(gid)) assert.ok(conn.chats.get(gid))
assert.ok(conn.chats.get(gid).metadata) assert.ok(conn.chats.get(gid).metadata)
}) })
@@ -107,8 +107,8 @@ WAConnectionTest('Groups', (conn) => {
console.log(participants) console.log(participants)
console.log(conn.chats.get(jid).metadata) console.log(conn.chats.get(jid).metadata)
assert.ok( assert.ok(
conn.chats.get(jid).metadata.participants.find(({ id, isAdmin }) => ( conn.chats.get(jid).metadata.participants.find(({ jid, isAdmin }) => (
whatsappID(id) === whatsappID(participants[0]) && isAdmin whatsappID(jid) === whatsappID(participants[0]) && isAdmin
)), )),
) )
resolve() resolve()
@@ -122,14 +122,14 @@ WAConnectionTest('Groups', (conn) => {
it('should remove someone from a group', async () => { it('should remove someone from a group', async () => {
const metadata = await conn.groupMetadata (gid) const metadata = await conn.groupMetadata (gid)
if (metadata.participants.find(({id}) => whatsappID(id) === testJid)) { if (metadata.participants.find(({jid}) => whatsappID(jid) === testJid)) {
const waitForEvent = new Promise (resolve => { const waitForEvent = new Promise (resolve => {
conn.once ('group-participants-update', ({jid, participants, action}) => { conn.once ('group-participants-update', ({jid, participants, action}) => {
if (jid === gid) { if (jid === gid) {
assert.strictEqual (participants[0], testJid) assert.strictEqual (participants[0], testJid)
assert.strictEqual (action, 'remove') assert.strictEqual (action, 'remove')
assert.deepStrictEqual( assert.deepStrictEqual(
conn.chats.get(jid).metadata.participants.find(p => whatsappID(p.id) === whatsappID(participants[0])), conn.chats.get(jid).metadata.participants.find(p => whatsappID(p.jid) === whatsappID(participants[0])),
undefined undefined
) )
resolve () resolve ()

View File

@@ -5,8 +5,6 @@ import { WAConnectionTest, testJid, sendAndRetreiveMessage, assertChatDBIntegrit
WAConnectionTest('Messages', conn => { WAConnectionTest('Messages', conn => {
afterEach (() => assertChatDBIntegrity (conn))
it('should send a text message', async () => { it('should send a text message', async () => {
const message = await sendAndRetreiveMessage(conn, 'hello fren', MessageType.text) const message = await sendAndRetreiveMessage(conn, 'hello fren', MessageType.text)
assert.strictEqual(message.message.conversation || message.message.extendedTextMessage?.text, 'hello fren') assert.strictEqual(message.message.conversation || message.message.extendedTextMessage?.text, 'hello fren')
@@ -190,14 +188,22 @@ WAConnectionTest('Messages', conn => {
]) ])
assert.strictEqual (results[0].messages.length, results[1].messages.length) assert.strictEqual (results[0].messages.length, results[1].messages.length)
for (let i = 0; i < results[1].messages.length;i++) { for (let i = 0; i < results[1].messages.length;i++) {
assert.deepStrictEqual (results[0].messages[i], results[1].messages[i], `failed equal at ${i}`) assert.deepStrictEqual (
results[0].messages[i].key,
results[1].messages[i].key,
`failed equal at ${i}`
)
} }
assert.ok (results[0].messages.length <= 50) assert.ok (results[0].messages.length <= 50)
// check if messages match server // check if messages match server
let msgs = await conn.fetchMessagesFromWA (testJid, 50) let msgs = await conn.fetchMessagesFromWA (testJid, 50)
for (let i = 0; i < results[1].messages.length;i++) { for (let i = 0; i < results[1].messages.length;i++) {
assert.deepStrictEqual (results[0].messages[i].key, msgs[i].key, `failed equal at ${i}`) assert.deepStrictEqual (
results[0].messages[i].key,
msgs[i].key,
`failed equal at ${i}`
)
} }
// check with some arbitary cursors // check with some arbitary cursors
let cursor = results[0].messages.slice(-1)[0].key let cursor = results[0].messages.slice(-1)[0].key
@@ -205,7 +211,11 @@ WAConnectionTest('Messages', conn => {
msgs = await conn.fetchMessagesFromWA (testJid, 20, cursor) msgs = await conn.fetchMessagesFromWA (testJid, 20, cursor)
let {messages} = await conn.loadMessages (testJid, 20, cursor) let {messages} = await conn.loadMessages (testJid, 20, cursor)
for (let i = 0; i < messages.length;i++) { for (let i = 0; i < messages.length;i++) {
assert.deepStrictEqual (messages[i].key, msgs[i].key, `failed equal at ${i}`) assert.deepStrictEqual (
messages[i].key,
msgs[i].key,
`failed equal at ${i}`
)
} }
for (let i = 0; i < 3;i++) { for (let i = 0; i < 3;i++) {
cursor = results[0].messages[i].key cursor = results[0].messages[i].key

View File

@@ -2,9 +2,10 @@ import { Presence, ChatModification, delay, newMessagesDB } from '../WAConnectio
import { promises as fs } from 'fs' import { promises as fs } from 'fs'
import * as assert from 'assert' import * as assert from 'assert'
import fetch from 'node-fetch' import fetch from 'node-fetch'
import { WAConnectionTest, testJid } from './Common' import { WAConnectionTest, testJid, assertChatDBIntegrity } from './Common'
WAConnectionTest('Misc', conn => {
WAConnectionTest('Misc', (conn) => {
it('should tell if someone has an account on WhatsApp', async () => { it('should tell if someone has an account on WhatsApp', async () => {
const response = await conn.isOnWhatsApp(testJid) const response = await conn.isOnWhatsApp(testJid)
assert.strictEqual(response, true) assert.strictEqual(response, true)
@@ -159,7 +160,9 @@ WAConnectionTest('Misc', (conn) => {
// this test requires quite a few messages with the test JID // this test requires quite a few messages with the test JID
it('should detect overlaps and clear messages accordingly', async () => { it('should detect overlaps and clear messages accordingly', async () => {
// wait for chats // wait for chats
await new Promise(resolve => conn.once('chats-received', resolve)) await new Promise(resolve => (
conn.once('chats-received', ({ hasReceivedLastMessage }) => hasReceivedLastMessage && resolve())
))
conn.maxCachedMessages = 100 conn.maxCachedMessages = 100
@@ -174,7 +177,7 @@ WAConnectionTest('Misc', (conn) => {
// remove all latest messages // remove all latest messages
chat.messages = newMessagesDB( chat.messages.all().slice(0, 20) ) chat.messages = newMessagesDB( chat.messages.all().slice(0, 20) )
const task = new Promise((resolve, reject) => ( const task = new Promise(resolve => (
conn.on('chats-received', ({ hasReceivedLastMessage, chatsWithMissingMessages }) => { conn.on('chats-received', ({ hasReceivedLastMessage, chatsWithMissingMessages }) => {
if (hasReceivedLastMessage) { if (hasReceivedLastMessage) {
assert.strictEqual(Object.keys(chatsWithMissingMessages).length, 1) assert.strictEqual(Object.keys(chatsWithMissingMessages).length, 1)
@@ -191,6 +194,7 @@ WAConnectionTest('Misc', (conn) => {
)) ))
await conn.connect() await conn.connect()
await task await task
}) })
}) })

View File

@@ -97,7 +97,7 @@ export class WAConnection extends Base {
message['epoch'] = prevEpoch+1000 message['epoch'] = prevEpoch+1000
} }
if (chat.messages.get(mKeyID)) { if (chat.messages.get(mKeyID)) {
chat.messages.delete(message) chat.messages.delete(chat.messages.get(mKeyID))
overlaps[jid] = { ...(overlaps[jid] || { requiresOverlap: true }), didOverlap: true } overlaps[jid] = { ...(overlaps[jid] || { requiresOverlap: true }), didOverlap: true }
} }