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.
taskbot/tests/unit/services/group-sync.fetch-members.te...

99 lines
3.9 KiB
TypeScript

import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
import { GroupSyncService } from '../../../src/services/group-sync';
const ORIGINAL_FETCH = globalThis.fetch;
describe('GroupSyncService - fetchGroupMembersFromAPI (parsing y fallbacks)', () => {
const envBackup = { ...process.env };
beforeEach(() => {
process.env = {
...envBackup,
NODE_ENV: 'development', // evitar early-return de test
EVOLUTION_API_URL: 'http://evolution.test',
EVOLUTION_API_INSTANCE: 'instance-1',
EVOLUTION_API_KEY: 'apikey'
};
});
afterEach(() => {
process.env = envBackup;
globalThis.fetch = ORIGINAL_FETCH;
});
test('parsea /group/participants con múltiples formas de payload y roles', async () => {
globalThis.fetch = async (url: RequestInfo | URL) => {
if (String(url).includes('/group/participants/')) {
const body = {
participants: [
{ id: '553198296801@s.whatsapp.net', admin: 'superadmin' },
{ id: '1234567890@s.whatsapp.net', admin: 'admin' },
{ id: '1111111111@s.whatsapp.net', admin: null },
'2222222222@s.whatsapp.net',
{ jid: '3333333333@s.whatsapp.net', role: 'member' },
{ user: { id: '4444444444@s.whatsapp.net' }, isAdmin: true }
]
};
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('123@g.us');
// Debe mapear a IDs normalizados (solo dígitos) y detectar admin correctamente
const ids = out.map((x: any) => x.userId).sort();
expect(ids).toEqual(['1111111111','1234567890','2222222222','3333333333','4444444444','553198296801'].sort());
const adminMap = new Map(out.map((x: any) => [x.userId, x.isAdmin]));
expect(adminMap.get('553198296801')).toBe(true);
expect(adminMap.get('1234567890')).toBe(true);
expect(adminMap.get('1111111111')).toBe(false);
expect(adminMap.get('2222222222')).toBe(false);
expect(adminMap.get('3333333333')).toBe(false);
expect(adminMap.get('4444444444')).toBe(true);
});
test('fallback a fetchAllGroups cuando /group/participants no trae participants', async () => {
globalThis.fetch = async (url: RequestInfo | URL) => {
const u = String(url);
if (u.includes('/group/participants/')) {
// OK pero sin campo participants
return new Response(JSON.stringify({ ok: true }), { status: 200 });
}
if (u.includes('/group/fetchAllGroups/')) {
const wrapped = {
response: [
{ id: '123@g.us', participants: [{ id: '9999999999@s.whatsapp.net', admin: 'admin' }] }
]
};
return new Response(JSON.stringify(wrapped), { status: 200, headers: { 'Content-Type': 'application/json' } });
}
return new Response('not found', { status: 404 });
};
const out = await (GroupSyncService as any).fetchGroupMembersFromAPI('123@g.us');
expect(out).toEqual([{ userId: '9999999999', isAdmin: true }]);
});
test('fallback devuelve snapshot vacío si el grupo no está presente', async () => {
globalThis.fetch = async (url: RequestInfo | URL) => {
const u = String(url);
if (u.includes('/group/participants/')) {
return new Response(JSON.stringify({ ok: true }), { status: 200 });
}
if (u.includes('/group/fetchAllGroups/')) {
const wrapped = {
response: [
{ id: 'other@g.us', participants: [{ id: '9999999999@s.whatsapp.net', admin: 'admin' }] }
]
};
return new Response(JSON.stringify(wrapped), { status: 200 });
}
return new Response('not found', { status: 404 });
};
const out = await (GroupSyncService as any).fetchGroupMembersFromAPI('123@g.us');
expect(out).toEqual([]);
});
});