import { WhatsAppSessionPool } from './session-pool'; // Mock createWhatsAppSession so we don't need a real WhatsApp connection jest.mock('./session', () => ({ createWhatsAppSession: jest.fn().mockResolvedValue({ sendMessage: jest.fn().mockResolvedValue({}), logout: jest.fn().mockResolvedValue({}), end: jest.fn(), }), })); describe('WhatsAppSessionPool', () => { let pool: WhatsAppSessionPool; beforeEach(() => { pool = new WhatsAppSessionPool(); jest.clearAllMocks(); }); it('add() stores a session by accountId', async () => { await pool.add('acc_1', './sessions/1', jest.fn(), jest.fn(), jest.fn()); expect(pool.get('acc_1')).toBeDefined(); }); it('get() returns undefined for unknown accountId', () => { expect(pool.get('acc_unknown')).toBeUndefined(); }); it('getAll() returns the sessions map', async () => { await pool.add('acc_1', './sessions/1', jest.fn(), jest.fn(), jest.fn()); expect(pool.getAll().size).toBe(1); expect(pool.getAll().has('acc_1')).toBe(true); }); it('sendMessage() throws with informative error when no session exists', async () => { await expect(pool.sendMessage('acc_missing', '1234@g.us', 'hello')).rejects.toThrow( 'No active session for account acc_missing', ); }); it('sendMessage() includes available accounts in error when others exist', async () => { await pool.add('acc_1', './sessions/1', jest.fn(), jest.fn(), jest.fn()); await expect(pool.sendMessage('acc_missing', '1234@g.us', 'hello')).rejects.toThrow( 'Active accounts: [acc_1]', ); }); it('remove() removes session from pool', async () => { await pool.add('acc_1', './sessions/1', jest.fn(), jest.fn(), jest.fn()); expect(pool.get('acc_1')).toBeDefined(); await pool.remove('acc_1'); expect(pool.get('acc_1')).toBeUndefined(); }); it('remove() is a no-op for unknown accountId', async () => { await expect(pool.remove('acc_unknown')).resolves.not.toThrow(); }); it('closeAll() calls end() on all sessions and clears the pool', async () => { await pool.add('acc_1', './sessions/1', jest.fn(), jest.fn(), jest.fn()); await pool.add('acc_2', './sessions/2', jest.fn(), jest.fn(), jest.fn()); expect(pool.getAll().size).toBe(2); const sock1 = pool.get('acc_1')!; const sock2 = pool.get('acc_2')!; await pool.closeAll(); expect(sock1.end).toHaveBeenCalledWith(expect.objectContaining({ message: 'Shutdown' })); expect(sock2.end).toHaveBeenCalledWith(expect.objectContaining({ message: 'Shutdown' })); expect(pool.getAll().size).toBe(0); }); it('add() injects accountId into onMessage callback', async () => { const onMessage = jest.fn(); const { createWhatsAppSession } = require('./session'); let capturedOnMessage: any; (createWhatsAppSession as jest.Mock).mockImplementationOnce( (_accountId: string, _path: string, cb: any) => { capturedOnMessage = cb; return Promise.resolve({ sendMessage: jest.fn(), logout: jest.fn() }); }, ); await pool.add('acc_1', './sessions/1', onMessage, jest.fn(), jest.fn()); const fakeMsg = { platformMsgId: 'abc', content: 'hi', sourceGroupJid: '1@g.us', senderJid: '2@s.whatsapp.net', accountId: 'acc_1' }; await capturedOnMessage(fakeMsg); expect(onMessage).toHaveBeenCalledWith(fakeMsg, 'acc_1'); }); it('add() injects accountId into onQr callback', async () => { const onQr = jest.fn(); const { createWhatsAppSession } = require('./session'); let capturedOnQr: any; (createWhatsAppSession as jest.Mock).mockImplementationOnce( (_id: string, _path: string, _onMsg: any, _onReaction: any, _onGroups: any, _onReconnect: any, qrCb: any) => { capturedOnQr = qrCb; return Promise.resolve({ sendMessage: jest.fn(), logout: jest.fn(), end: jest.fn() }); }, ); await pool.add('acc_1', './sessions/1', jest.fn(), jest.fn(), jest.fn(), onQr); await capturedOnQr('test-qr'); expect(onQr).toHaveBeenCalledWith('test-qr', 'acc_1'); }); it('add() injects accountId and jid into onStatus callback', async () => { const onStatus = jest.fn(); const { createWhatsAppSession } = require('./session'); let capturedOnStatus: any; (createWhatsAppSession as jest.Mock).mockImplementationOnce( (_id: string, _path: string, _onMsg: any, _onReaction: any, _onGroups: any, _onReconnect: any, _onQr: any, statusCb: any) => { capturedOnStatus = statusCb; return Promise.resolve({ sendMessage: jest.fn(), logout: jest.fn(), end: jest.fn() }); }, ); await pool.add('acc_1', './sessions/1', jest.fn(), jest.fn(), jest.fn(), undefined, onStatus); await capturedOnStatus('connected', '1234@s.whatsapp.net'); expect(onStatus).toHaveBeenCalledWith('connected', 'acc_1', '1234@s.whatsapp.net'); }); });