test: actualiza pruebas unitarias de BD a nuevas tablas y añade tests
Co-authored-by: aider (openrouter/openai/gpt-5) <aider@aider.chat>pull/1/head
parent
61add46ede
commit
e7d3596005
@ -0,0 +1,108 @@
|
|||||||
|
import { Database } from 'bun:sqlite';
|
||||||
|
import { beforeAll, beforeEach, afterAll, describe, expect, test } from 'bun:test';
|
||||||
|
import { initializeDatabase } from '../../../src/db';
|
||||||
|
import { GroupSyncService } from '../../../src/services/group-sync';
|
||||||
|
|
||||||
|
describe('GroupSyncService - reconcileGroupMembers', () => {
|
||||||
|
let memdb: Database;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
memdb = new Database(':memory:');
|
||||||
|
memdb.exec('PRAGMA foreign_keys = ON;');
|
||||||
|
initializeDatabase(memdb);
|
||||||
|
// Inyectar DB en el servicio
|
||||||
|
GroupSyncService.dbInstance = memdb as any;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
memdb.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
// Limpiar tablas relevantes entre tests
|
||||||
|
memdb.exec('DELETE FROM group_members');
|
||||||
|
memdb.exec('DELETE FROM users');
|
||||||
|
memdb.exec('DELETE FROM groups');
|
||||||
|
|
||||||
|
// Crear grupo base activo
|
||||||
|
memdb.prepare(`INSERT INTO groups (id, community_id, name) VALUES (?, ?, ?)`)
|
||||||
|
.run('123@g.us', 'community-1', 'Grupo 123');
|
||||||
|
});
|
||||||
|
|
||||||
|
function getMember(userId: string) {
|
||||||
|
return memdb.prepare(`
|
||||||
|
SELECT group_id, user_id, is_admin, is_active, first_seen_at, last_seen_at, last_role_change_at
|
||||||
|
FROM group_members
|
||||||
|
WHERE group_id = ? AND user_id = ?
|
||||||
|
`).get('123@g.us', userId) as any;
|
||||||
|
}
|
||||||
|
|
||||||
|
test('inserta miembros y marca activos en la primera reconciliación', () => {
|
||||||
|
const res = GroupSyncService.reconcileGroupMembers('123@g.us', [
|
||||||
|
{ userId: '111', isAdmin: true },
|
||||||
|
{ userId: '222', isAdmin: false }
|
||||||
|
], '2025-01-01 00:00:00.000');
|
||||||
|
|
||||||
|
expect(res).toEqual({ added: 2, updated: 0, deactivated: 0 });
|
||||||
|
|
||||||
|
const m1 = getMember('111');
|
||||||
|
const m2 = getMember('222');
|
||||||
|
|
||||||
|
expect(m1).toBeDefined();
|
||||||
|
expect(m1.is_active).toBe(1);
|
||||||
|
expect(m1.is_admin).toBe(1);
|
||||||
|
expect(m1.first_seen_at).toBe('2025-01-01 00:00:00.000');
|
||||||
|
expect(m1.last_seen_at).toBe('2025-01-01 00:00:00.000');
|
||||||
|
|
||||||
|
expect(m2).toBeDefined();
|
||||||
|
expect(m2.is_active).toBe(1);
|
||||||
|
expect(m2.is_admin).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('actualiza roles, desactiva ausentes y añade nuevos en reconciliaciones posteriores', () => {
|
||||||
|
// Primera pasada
|
||||||
|
GroupSyncService.reconcileGroupMembers('123@g.us', [
|
||||||
|
{ userId: '111', isAdmin: true },
|
||||||
|
{ userId: '222', isAdmin: false }
|
||||||
|
], '2025-01-01 00:00:00.000');
|
||||||
|
|
||||||
|
// Segunda pasada con cambios: 111 pierde admin, 222 desaparece, 333 aparece
|
||||||
|
const res2 = GroupSyncService.reconcileGroupMembers('123@g.us', [
|
||||||
|
{ userId: '111', isAdmin: false },
|
||||||
|
{ userId: '333', isAdmin: false }
|
||||||
|
], '2025-01-02 00:00:00.000');
|
||||||
|
|
||||||
|
expect(res2).toEqual({ added: 1, updated: 1, deactivated: 1 });
|
||||||
|
|
||||||
|
const m111 = getMember('111');
|
||||||
|
const m222 = getMember('222');
|
||||||
|
const m333 = getMember('333');
|
||||||
|
|
||||||
|
expect(m111.is_active).toBe(1);
|
||||||
|
expect(m111.is_admin).toBe(0);
|
||||||
|
expect(m111.last_role_change_at).toBe('2025-01-02 00:00:00.000');
|
||||||
|
expect(m222.is_active).toBe(0);
|
||||||
|
expect(m333.is_active).toBe(1);
|
||||||
|
expect(m333.is_admin).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('idempotencia: aplicar mismo snapshot no altera contadores y actualiza last_seen_at', () => {
|
||||||
|
GroupSyncService.reconcileGroupMembers('123@g.us', [
|
||||||
|
{ userId: '111', isAdmin: false },
|
||||||
|
{ userId: '333', isAdmin: false }
|
||||||
|
], '2025-01-02 00:00:00.000');
|
||||||
|
|
||||||
|
const res3 = GroupSyncService.reconcileGroupMembers('123@g.us', [
|
||||||
|
{ userId: '111', isAdmin: false },
|
||||||
|
{ userId: '333', isAdmin: false }
|
||||||
|
], '2025-01-03 00:00:00.000');
|
||||||
|
|
||||||
|
expect(res3).toEqual({ added: 0, updated: 0, deactivated: 0 });
|
||||||
|
|
||||||
|
const m111 = getMember('111');
|
||||||
|
const m333 = getMember('333');
|
||||||
|
|
||||||
|
expect(m111.last_seen_at).toBe('2025-01-03 00:00:00.000');
|
||||||
|
expect(m333.last_seen_at).toBe('2025-01-03 00:00:00.000');
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue