import { describe, it, expect, beforeEach, afterAll, mock } from 'bun:test'; import { GroupSyncService } from '../../../src/services/group-sync'; import { db } from '../../../src/db'; // Store original globals const originalEnv = { ...process.env }; const originalFetch = globalThis.fetch; process.env = { WHATSAPP_COMMUNITY_ID: 'test-community', EVOLUTION_API_URL: 'http://test-api', EVOLUTION_API_INSTANCE: 'test-instance', EVOLUTION_API_KEY: 'test-key', ...process.env }; // Mock fetch const fetchMock = mock(async () => ({ ok: true, json: async () => [ { id: 'group1', subject: 'Group 1', linkedParent: 'test-community' }, { id: 'group2', subject: 'Group 2', linkedParent: 'other-community' }, { id: 'group3', subject: 'Group 3' } // No linkedParent ] })); // Replace global fetch globalThis.fetch = fetchMock; describe('GroupSyncService', () => { beforeEach(() => { db.exec('DELETE FROM groups'); GroupSyncService['lastSyncAttempt'] = 0; // Reset process.env to mock values process.env.WHATSAPP_COMMUNITY_ID = 'test-community'; process.env.EVOLUTION_API_URL = 'http://test-api'; process.env.EVOLUTION_API_INSTANCE = 'test-instance'; process.env.EVOLUTION_API_KEY = 'test-key'; }); afterAll(() => { // Restore original process.env process.env.WHATSAPP_COMMUNITY_ID = originalEnv.WHATSAPP_COMMUNITY_ID; process.env.EVOLUTION_API_URL = originalEnv.EVOLUTION_API_URL; process.env.EVOLUTION_API_INSTANCE = originalEnv.EVOLUTION_API_INSTANCE; process.env.EVOLUTION_API_KEY = originalEnv.EVOLUTION_API_KEY; // Restore original fetch globalThis.fetch = originalFetch; }); describe('syncGroups', () => { it('should skip sync if called too soon', async () => { GroupSyncService['lastSyncAttempt'] = Date.now() - 1000; const result = await GroupSyncService.syncGroups(); expect(result).toEqual({ added: 0, updated: 0 }); expect(mockFetch).not.toHaveBeenCalled(); }); it('should throw if WHATSAPP_COMMUNITY_ID is missing', async () => { env.WHATSAPP_COMMUNITY_ID = ''; await expect(GroupSyncService.syncGroups()).rejects.toThrow('WHATSAPP_COMMUNITY_ID is not set'); }); it('should filter groups by community ID', async () => { const result = await GroupSyncService.syncGroups(); expect(result.added).toBe(1); expect(result.updated).toBe(0); const groups = db.query('SELECT * FROM groups').all(); expect(groups).toHaveLength(1); expect(groups[0].id).toBe('group1'); }); it('should update existing groups', async () => { // Add initial group db.exec( "INSERT INTO groups (id, community_id, name, active) VALUES ('group1', 'test-community', 'Old Name', TRUE)" ); const result = await GroupSyncService.syncGroups(); expect(result.added).toBe(0); expect(result.updated).toBe(1); const group = db.query('SELECT * FROM groups WHERE id = ?').get('group1'); expect(group.name).toBe('Group 1'); expect(group.active).toBe(1); }); it('should mark non-matching groups as inactive', async () => { // Add initial group not in current sync db.exec( "INSERT INTO groups (id, community_id, name, active) VALUES ('old-group', 'test-community', 'Old Group', TRUE)" ); await GroupSyncService.syncGroups(); const group = db.query('SELECT active FROM groups WHERE id = ?').get('old-group'); expect(group.active).toBe(0); }); it('should handle API errors', async () => { globalThis.fetch = mock(async () => ({ ok: false, statusText: 'Not Found' })); await expect(GroupSyncService.syncGroups()).rejects.toThrow('API request failed: Not Found'); }); }); });