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.

152 lines
4.8 KiB
TypeScript

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 originalFetch = globalThis.fetch;
const originalConsoleError = console.error;
describe('GroupSyncService', () => {
let fetchMock: any;
beforeEach(() => {
// Clear and reset test data
db.exec('DELETE FROM groups');
db.exec('DELETE FROM sqlite_sequence WHERE name="groups"');
GroupSyncService['lastSyncAttempt'] = 0;
// Setup mock fetch
fetchMock = mock(async () => ({
ok: true,
json: async () => ({
status: 'success',
response: [
{ id: 'group1', subject: 'Group 1', linkedParent: 'test-community' },
{ id: 'group2', subject: 'Group 2', linkedParent: 'other-community' },
{ id: 'group3', subject: 'Group 3' } // No linkedParent
]
})
}));
globalThis.fetch = fetchMock;
// Setup env vars
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(() => {
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(fetchMock).not.toHaveBeenCalled();
});
it('should throw if WHATSAPP_COMMUNITY_ID is missing', async () => {
const consoleErrorMock = mock(() => {});
console.error = consoleErrorMock;
process.env.WHATSAPP_COMMUNITY_ID = '';
await expect(GroupSyncService.syncGroups())
.rejects.toThrow('WHATSAPP_COMMUNITY_ID is not set');
expect(consoleErrorMock).toHaveBeenCalledWith(
'Group sync failed:',
expect.any(Error)
);
// Restore original console.error
console.error = originalConsoleError;
});
it('should filter groups by community ID', async () => {
// Reset last sync attempt to force a sync
GroupSyncService['lastSyncAttempt'] = 0;
const result = await GroupSyncService.syncGroups();
// Verify the correct groups were processed
expect(result).toEqual({
added: 1, // group1 should be added
updated: 0 // no existing groups to update
});
// Verify database state
const groups = db.query('SELECT * FROM groups').all();
expect(groups).toHaveLength(1);
const group = groups[0];
expect(group.id).toBe('group1');
expect(group.community_id).toBe('test-community');
expect(group.name).toBe('Group 1');
expect(group.active).toBe(1);
expect(group.last_verified).toBeTruthy();
// Verify only the matching group was processed
expect(fetchMock).toHaveBeenCalledTimes(1);
});
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', 1)"
);
const result = await GroupSyncService.syncGroups();
expect(result).toEqual({
added: 0,
updated: 1
});
const group = db.query('SELECT * FROM groups WHERE id = ?').get('group1');
expect(group).toEqual({
id: 'group1',
community_id: 'test-community',
name: 'Group 1',
active: 1,
last_verified: expect.any(String)
});
});
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, last_verified) VALUES ('old-group', 'test-community', 'Old Group', 1, '2023-01-01')"
);
await GroupSyncService.syncGroups();
const group = db.query('SELECT * FROM groups WHERE id = ?').get('old-group');
expect(group).toEqual({
id: 'old-group',
community_id: 'test-community',
name: 'Old Group',
active: 0,
last_verified: expect.any(String)
});
expect(group.last_verified).not.toBe('2023-01-01'); // Should be updated
});
it('should handle API errors', async () => {
const consoleErrorMock = mock(() => {});
console.error = consoleErrorMock;
globalThis.fetch = mock(async () => ({
ok: false,
statusText: 'Not Found'
}));
await expect(GroupSyncService.syncGroups()).rejects.toThrow('API request failed: Not Found');
expect(consoleErrorMock).toHaveBeenCalled();
console.error = originalConsoleError;
});
});
});