You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			86 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			86 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			TypeScript
		
	
| import { describe, it, beforeEach, afterEach, expect } from 'bun:test';
 | |
| import { Database } from 'bun:sqlite';
 | |
| import { initializeDatabase } from '../../../src/db';
 | |
| import { IdentityService } from '../../../src/services/identity';
 | |
| import { WebhookServer } from '../../../src/server';
 | |
| import { GroupSyncService } from '../../../src/services/group-sync';
 | |
| 
 | |
| const ORIGINAL_FETCH = globalThis.fetch;
 | |
| const envBackup = { ...process.env };
 | |
| 
 | |
| describe('Alias @lid ↔ número: aprendizaje y uso en sync de miembros', () => {
 | |
|   let memdb: Database;
 | |
| 
 | |
|   beforeEach(() => {
 | |
|     process.env = { ...envBackup };
 | |
|     memdb = new Database(':memory:');
 | |
|     memdb.exec('PRAGMA foreign_keys = ON;');
 | |
|     initializeDatabase(memdb);
 | |
| 
 | |
|     // Inyectar DB en servicios implicados
 | |
|     (IdentityService as any).dbInstance = memdb;
 | |
|     (WebhookServer as any).dbInstance = memdb;
 | |
|     (GroupSyncService as any).dbInstance = memdb;
 | |
| 
 | |
|     // Limpiar caché de grupos para evitar interferencias
 | |
|     GroupSyncService.activeGroupsCache.clear();
 | |
|   });
 | |
| 
 | |
|   afterEach(() => {
 | |
|     globalThis.fetch = ORIGINAL_FETCH;
 | |
|     process.env = envBackup;
 | |
|     memdb.close();
 | |
|   });
 | |
| 
 | |
|   it('aprende alias desde participantAlt y luego resuelve miembros con solo @lid', async () => {
 | |
|     // 1) Simular mensaje de grupo que trae participant (alias @lid) y participantAlt (número real)
 | |
|     process.env.NODE_ENV = 'test'; // evita efectos de red/timers
 | |
|     const payload = {
 | |
|       key: {
 | |
|         remoteJid: '12345-678@g.us',
 | |
|         participant: 'userXYZ@lid',
 | |
|         participantAlt: '666777888@s.whatsapp.net',
 | |
|         fromMe: false
 | |
|       },
 | |
|       message: { conversation: 'hola' }
 | |
|     };
 | |
| 
 | |
|     await WebhookServer.handleMessageUpsert(payload);
 | |
| 
 | |
|     // Verificar que el alias fue aprendido
 | |
|     const resolved = IdentityService.resolveAliasOrNull('userXYZ@lid');
 | |
|     expect(resolved).toBe('666777888');
 | |
| 
 | |
|     // Añadir un segundo alias manualmente para cubrir varios miembros
 | |
|     IdentityService.upsertAlias('abc@lid', '999000111@s.whatsapp.net', 'test-seed');
 | |
|     expect(IdentityService.resolveAliasOrNull('abc@lid')).toBe('999000111');
 | |
| 
 | |
|     // 2) Ahora simular la Evolution API devolviendo solo IDs con @lid en /group/participants
 | |
|     process.env.NODE_ENV = 'development'; // evitar early-return en fetchGroupMembersFromAPI
 | |
|     process.env.EVOLUTION_API_URL = 'http://evolution.test';
 | |
|     process.env.EVOLUTION_API_INSTANCE = 'instance-1';
 | |
|     process.env.EVOLUTION_API_KEY = 'apikey';
 | |
| 
 | |
|     globalThis.fetch = async (url: RequestInfo | URL) => {
 | |
|       if (String(url).includes('/group/participants/')) {
 | |
|         const body = {
 | |
|           participants: [
 | |
|             { id: 'userXYZ@lid', admin: 'admin' }, // debe resolverse a 666777888 (admin)
 | |
|             { id: 'abc@lid', admin: null }         // debe resolverse a 999000111 (no admin)
 | |
|           ]
 | |
|         };
 | |
|         return new Response(JSON.stringify(body), { status: 200, headers: { 'Content-Type': 'application/json' } });
 | |
|       }
 | |
|       return new Response('not found', { status: 404 });
 | |
|     };
 | |
| 
 | |
|     const out = await (GroupSyncService as any).fetchGroupMembersFromAPI('12345-678@g.us');
 | |
|     const map = new Map(out.map((x: any) => [x.userId, x.isAdmin]));
 | |
| 
 | |
|     expect(map.has('666777888')).toBe(true);
 | |
|     expect(map.has('999000111')).toBe(true);
 | |
|     expect(map.get('666777888')).toBe(true);   // admin resuelto
 | |
|     expect(map.get('999000111')).toBe(false);  // no admin
 | |
|   });
 | |
| });
 |