@@ -5,9 +5,11 @@ jest.mock('../../src/utils/audio_convert', () => ({
55jest . mock ( '../../src/defaults' , ( ) => {
66 const actual = jest . requireActual ( '../../src/defaults' )
77 return {
8- __esModule : true ,
9- ...actual ,
10- SEND_AUDIO_MESSAGE_AS_PTT : true ,
8+ __esModule : true ,
9+ ...actual ,
10+ SEND_AUDIO_MESSAGE_AS_PTT : true ,
11+ GROUP_METADATA_EVENT_REFRESH_DEBOUNCE_MS : 10 ,
12+ GROUP_METADATA_EVENT_REFRESH_MIN_INTERVAL_MS : 0 ,
1113 }
1214} )
1315jest . mock ( '../../src/services/socket' )
@@ -32,11 +34,12 @@ import {
3234 rejectCall ,
3335 sendCallNode ,
3436 fetchImageUrl ,
35- fetchGroupMetadata ,
36- exists ,
37- close ,
38- logout ,
39- } from '../../src/services/socket'
37+ fetchGroupMetadata ,
38+ groupMetadata ,
39+ exists ,
40+ close ,
41+ logout ,
42+ } from '../../src/services/socket'
4043import { mock , mockFn } from 'jest-mock-extended'
4144import { proto } from '@whiskeysockets/baileys'
4245import { DataStore } from '../../src/services/data_store'
@@ -74,6 +77,7 @@ describe('service client baileys', () => {
7477 let sendCallNodeMock
7578 let fetchImageUrl
7679 let fetchGroupMetadata
80+ let groupMetadataMock
7781 let getConfig : getConfig
7882 let config : Config
7983 let close : close
@@ -116,11 +120,12 @@ describe('service client baileys', () => {
116120 logout = mockFn < logout > ( )
117121 fetchImageUrl = mockFn < fetchImageUrl > ( )
118122 fetchGroupMetadata = mockFn < fetchGroupMetadata > ( )
123+ groupMetadataMock = mockFn < groupMetadata > ( )
119124 const capturedEvent = ( name , callback ) => {
120125 eventHandlers [ name ] = callback
121126 return event ( name , callback )
122127 }
123- mockConnect . mockResolvedValue ( { event : capturedEvent as any , status, send, read, rejectCall, sendCallNode : sendCallNodeMock , fetchImageUrl, fetchGroupMetadata, exists, close, logout } )
128+ mockConnect . mockResolvedValue ( { event : capturedEvent as any , status, send, read, rejectCall, sendCallNode : sendCallNodeMock , fetchImageUrl, fetchGroupMetadata, groupMetadata : groupMetadataMock , exists, close, logout } )
124129 } )
125130
126131 test ( 'call send with unknown status' , async ( ) => {
@@ -157,6 +162,44 @@ describe('service client baileys', () => {
157162 expect ( response . ok . messages [ 0 ] . id ) . toBe ( `uno-${ id } ` )
158163 } )
159164
165+ test ( 'recovers delivery by refreshing sessions and resending with mapped provider id' , async ( ) => {
166+ const unoId = 'uno-message-1'
167+ const providerId = 'provider-message-1'
168+ dataStore . loadProviderId . mockResolvedValue ( providerId )
169+ dataStore . loadUnoId . mockImplementation ( async ( id : string ) => id === providerId ? unoId : undefined )
170+ send . mockResolvedValue ( {
171+ key : { id : providerId , remoteJid : '5566996810064@s.whatsapp.net' } ,
172+ message : { conversation : 'reenviar agora' } ,
173+ } )
174+
175+ await client . connect ( 0 )
176+ const response = await client . recoverDelivery ! ( {
177+ message_id : unoId ,
178+ to : '5566996810064' ,
179+ type : 'text' ,
180+ text : { body : 'reenviar agora' } ,
181+ } , { } )
182+
183+ expect ( send ) . toHaveBeenCalledWith (
184+ '5566996810064@s.whatsapp.net' ,
185+ expect . objectContaining ( { text : 'reenviar agora' } ) ,
186+ expect . objectContaining ( {
187+ messageId : providerId ,
188+ forceDeliveryRecovery : true ,
189+ forceSessionRefresh : true ,
190+ forceDeviceList : true ,
191+ useUserDevicesCache : false ,
192+ } ) ,
193+ )
194+ expect ( dataStore . setUnoId ) . toHaveBeenCalledWith ( providerId , unoId )
195+ expect ( response . ok . messages [ 0 ] . id ) . toBe ( unoId )
196+ expect ( ( response . ok as any ) . recovery ) . toEqual ( expect . objectContaining ( {
197+ attempted : true ,
198+ message_id : unoId ,
199+ provider_id : providerId ,
200+ } ) )
201+ } )
202+
160203 test ( 'call send with recipient_type group normalizes destination and response ids' , async ( ) => {
161204 const id = `${ new Date ( ) . getMilliseconds ( ) } `
162205 send . mockResolvedValue ( { key : { id, remoteJid : '120363040468224422@g.us' } } )
@@ -181,8 +224,45 @@ describe('service client baileys', () => {
181224 expect ( response . ok . messages [ 0 ] . id ) . toBe ( `uno-${ id } ` )
182225 } )
183226
227+ test ( 'refreshes group metadata cache after group participants update event' , async ( ) => {
228+ const groupJid = '120363040468224422@g.us'
229+ const metadata = {
230+ id : groupJid ,
231+ subject : 'Grupo atualizado' ,
232+ participants : [
233+ { id : '5566996222471@s.whatsapp.net' } ,
234+ { id : '11343495192601@lid' } ,
235+ ] ,
236+ }
237+ groupMetadataMock . mockResolvedValue ( metadata )
238+
239+ await client . connect ( 0 )
240+ await eventHandlers [ 'group-participants.update' ] ?.( {
241+ id : groupJid ,
242+ participants : [ '5566996222471@s.whatsapp.net' ] ,
243+ action : 'add' ,
244+ } )
245+ await new Promise ( ( resolve ) => setTimeout ( resolve , 20 ) )
246+
247+ expect ( groupMetadataMock ) . toHaveBeenCalledWith ( groupJid )
248+ expect ( dataStore . setGroupMetada ) . toHaveBeenCalledWith ( groupJid , metadata )
249+ } )
250+
251+ test ( 'refreshes group metadata cache after groups update event' , async ( ) => {
252+ const groupJid = '120363040468224422@g.us'
253+ const metadata = { id : groupJid , subject : 'Novo nome' , participants : [ ] }
254+ groupMetadataMock . mockResolvedValue ( metadata )
255+
256+ await client . connect ( 0 )
257+ await eventHandlers [ 'groups.update' ] ?.( [ { id : groupJid , subject : 'Novo nome' } ] )
258+ await new Promise ( ( resolve ) => setTimeout ( resolve , 20 ) )
259+
260+ expect ( groupMetadataMock ) . toHaveBeenCalledWith ( groupJid )
261+ expect ( dataStore . setGroupMetada ) . toHaveBeenCalledWith ( groupJid , metadata )
262+ } )
263+
184264 test ( 'call send with message type unknown' , async ( ) => {
185- const type = `${ new Date ( ) . getMilliseconds ( ) } `
265+ const type = `${ new Date ( ) . getMilliseconds ( ) } `
186266 try {
187267 await client . connect ( 0 )
188268 await client . send ( { type } , { } )
@@ -198,7 +278,7 @@ describe('service client baileys', () => {
198278 send = async ( ) => {
199279 throw new SendError ( 1 , '' )
200280 }
201- mockConnect . mockResolvedValue ( { event, status, send, read, rejectCall, sendCallNode : sendCallNodeMock , fetchImageUrl, fetchGroupMetadata, exists, close, logout } )
281+ mockConnect . mockResolvedValue ( { event, status, send, read, rejectCall, sendCallNode : sendCallNodeMock , fetchImageUrl, fetchGroupMetadata, groupMetadata : groupMetadataMock , exists, close, logout } )
202282 await client . connect ( 0 )
203283 const response = await client . send ( payload , { } )
204284 expect ( response . error . entry . length ) . toBe ( 1 )
@@ -293,6 +373,23 @@ describe('service client baileys', () => {
293373 expect ( send ) . toHaveBeenCalledWith ( '556696923653@s.whatsapp.net' , { text : config . rejectCalls } , { } )
294374 } )
295375
376+ test ( 'call offer rejects as incoming call when Baileys sends LID identity' , async ( ) => {
377+ config . rejectCalls = 'Nao posso atender agora'
378+ await client . connect ( 0 )
379+
380+ await eventHandlers . call ?.( [
381+ {
382+ from : '123456789012345@lid' ,
383+ callerPn : '556696923653@s.whatsapp.net' ,
384+ id : 'call-offer-1' ,
385+ status : 'offer' ,
386+ } ,
387+ ] )
388+
389+ expect ( rejectCall ) . toHaveBeenCalledWith ( 'call-offer-1' , '123456789012345@lid' )
390+ expect ( send ) . toHaveBeenCalledWith ( '556696923653@s.whatsapp.net' , { text : config . rejectCalls } , { } )
391+ } )
392+
296393 test ( 'call ringing falls back to from when callerPn is absent' , async ( ) => {
297394 config . rejectCalls = 'Nao posso atender agora'
298395 await client . connect ( 0 )
0 commit comments