diff --git a/CLAUDE.md b/CLAUDE.md index e1c459d..b4d4739 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -43,7 +43,7 @@ bun test # 8 tests unitaires socketio-adapter - **Sessions webview isolées** : partition Electron unique par centre, auto-connexion via preload script - **Socket.IO reconnexion** : illimitée (2s→10s backoff) - **IPC principal** : `login-agent`, `get-terminal-list`, `server-status`, `switch-to-center`, `release-center` -- **Protocole serveur** : auth au handshake, events `login_ok`/`login_error`/`ipbx_event`/`logout`→`logout_ok` +- **Protocole serveur** : auth au handshake, events `login_ok`/`login_error`/`call_event`/`logout`→`logout_ok` (champs snake_case : `event_code`, `queue_name`, `terminal`) - **Terminaux** : REST `GET /terminals?provider=RDVPREM` (pas Socket.IO) - **Logs** : `~/.simpleconnect-ng/socketio.log` - **Notes** : sauvegarde auto après 2s d'inactivité, 50 versions, sync localStorage + fichier diff --git a/main.js b/main.js index 18dc6a1..eff2f86 100644 --- a/main.js +++ b/main.js @@ -208,19 +208,19 @@ function handleCallPickedUp(event) { if (!mainWindow || !agentConnectionInfo) return; const centres = processApplicationUrls(agentConnectionInfo.connList); - const centre = centres.find(c => c.queueName === event.queueName); + const centre = centres.find(c => c.queueName === event.queue_name); if (centre) { log(`Basculement vers le centre: ${centre.nom}`); mainWindow.webContents.send('switch-to-center', { centreId: centre.id, centreName: centre.nom, - queueName: event.queueName, + queue_name: event.queue_name, terminal: event.terminal, eventType: 'call_pickup' }); } else { - log(`${c.yellow}Aucun centre trouvé pour la file: ${event.queueName}${c.reset}`); + log(`${c.yellow}Aucun centre trouvé pour la file: ${event.queue_name}${c.reset}`); } } @@ -228,9 +228,9 @@ function handleCallPickedUp(event) { function handleCallHungUp(event) { if (!mainWindow) return; - log(`Fin d'appel sur la file: ${event.queueName}`); + log(`Fin d'appel sur la file: ${event.queue_name}`); mainWindow.webContents.send('release-center', { - queueName: event.queueName, + queue_name: event.queue_name, terminal: event.terminal, eventType: 'call_hangup' }); @@ -245,9 +245,9 @@ function setupEventHandlers() { serviceProvider: config.socketio.serviceProvider }); - // Ecouter les evenements d'appels IPBX - adapter.on('ipbx_event', (data) => { - log('ipbx_event recu', data); + // Ecouter les evenements d'appels IPBX (contrat snake_case du serveur) + adapter.on('call_event', (data) => { + log('call_event recu', data); if (!agentConnectionInfo) return; @@ -257,7 +257,7 @@ function setupEventHandlers() { return; } - switch (data.eventCode) { + switch (data.event_code) { case 1: handleCallPickedUp(data); break; diff --git a/renderer.js b/renderer.js index 8fb95bb..835e214 100644 --- a/renderer.js +++ b/renderer.js @@ -153,7 +153,7 @@ document.addEventListener('DOMContentLoaded', async () => { // Écouter la libération de centre après raccrochage ipcRenderer.on('release-center', (event, data) => { - console.log('Libération de la file:', data.queueName); + console.log('Libération de la file:', data.queue_name); // Mettre à jour le statut updateAgentStatus('DISPONIBLE'); diff --git a/socketio-adapter.test.js b/socketio-adapter.test.js index 9838eb1..0a68db8 100644 --- a/socketio-adapter.test.js +++ b/socketio-adapter.test.js @@ -128,4 +128,63 @@ describe("SocketIOAdapter", () => { expect(states).toEqual(["connecting", "connected", "reconnecting", "connected"]); }); + + test("on('call_event') recoit les champs snake_case du serveur", async () => { + const received = []; + adapter.on('call_event', (data) => received.push(data)); + + const p = adapter.connect("1234", "pass", "2001"); + socket._fire("login_ok", { accessCode: "1234" }); + await p; + + // Le serveur envoie un call_event avec champs snake_case + socket._fire("call_event", { + event_code: 1, + queue_name: "FILE_CENTRE_A", + terminal: "2001", + }); + + expect(received).toHaveLength(1); + expect(received[0].event_code).toBe(1); + expect(received[0].queue_name).toBe("FILE_CENTRE_A"); + expect(received[0].terminal).toBe("2001"); + }); + + test("on('call_event') enregistré avant connect() est dispatché après connexion", async () => { + const received = []; + // Enregistrer le handler AVANT connect (comme le fait main.js) + adapter.on('call_event', (data) => received.push(data)); + + const p = adapter.connect("1234", "pass", "2001"); + socket._fire("login_ok", { accessCode: "1234" }); + await p; + + // Le serveur envoie un call_event + socket._fire("call_event", { + event_code: 2, + queue_name: "FILE_CENTRE_B", + terminal: "2001", + }); + + expect(received).toHaveLength(1); + expect(received[0].event_code).toBe(2); + expect(received[0].queue_name).toBe("FILE_CENTRE_B"); + }); + + test("off('call_event') supprime le handler", async () => { + const received = []; + adapter.on('call_event', (data) => received.push(data)); + + const p = adapter.connect("1234", "pass", "2001"); + socket._fire("login_ok", { accessCode: "1234" }); + await p; + + // Supprimer le handler + adapter.off('call_event'); + + // L'event ne devrait plus être capté + socket._fire("call_event", { event_code: 1, queue_name: "FILE", terminal: "2001" }); + + expect(received).toHaveLength(0); + }); });