From 8969b057730f5ac9d6f061cc68fcbf69ecc2ceb1 Mon Sep 17 00:00:00 2001
From: Nico Alt <nicoalt@posteo.org>
Date: Thu, 16 Jul 2020 13:52:27 -0400
Subject: [PATCH] Add method to watch connection state of contacts

Related to:
* https://code.briarproject.org/briar/briar-gtk/-/issues/19
* https://code.briarproject.org/briar/briar/-/merge_requests/1260
---
 briar_wrapper/models/contacts.py            | 22 +++++++++++++++++++
 tests/briar_wrapper/models/test_contacts.py | 24 +++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/briar_wrapper/models/contacts.py b/briar_wrapper/models/contacts.py
index 9619c28..81d6304 100644
--- a/briar_wrapper/models/contacts.py
+++ b/briar_wrapper/models/contacts.py
@@ -15,6 +15,9 @@ from briar_wrapper.model import Model
 class Contacts(Model):
 
     API_ENDPOINT = "contacts/"
+    CONNECTION_EVENTS = ("ContactConnectedEvent", "ContactDisconnectedEvent")
+
+    _connections_callback = None
 
     def add_pending(self, link, alias):
         url = urljoin(BASE_HTTP_URL, self.API_ENDPOINT + "add/pending/")
@@ -32,6 +35,25 @@ class Contacts(Model):
         request = _get(url, headers=self._headers).json()
         return request['link']
 
+    def watch_connections(self, callback):
+        self._connections_callback = callback
+        signal_ids = list()
+        event_callback = self._handle_connections_callback
+        for event in self.CONNECTION_EVENTS:
+            signal_id = self._api.socket_listener.connect(event,
+                                                          event_callback)
+            signal_ids.append(signal_id)
+        return signal_ids
+
+    def _handle_connections_callback(self, message):
+        contact_id = message["data"]["contactId"]
+        if message["name"] == "ContactConnectedEvent":
+            self._connections_callback(contact_id, True)
+        elif message["name"] == "ContactDisconnectedEvent":
+            self._connections_callback(contact_id, False)
+        else:
+            raise Exception(f"Wrong event in callback: {message['name']}")
+
     def _sort_contact_list(contacts):
         contacts.sort(key=itemgetter("lastChatActivity"),
                       reverse=True)
diff --git a/tests/briar_wrapper/models/test_contacts.py b/tests/briar_wrapper/models/test_contacts.py
index 1bc9879..3af6d2e 100644
--- a/tests/briar_wrapper/models/test_contacts.py
+++ b/tests/briar_wrapper/models/test_contacts.py
@@ -7,6 +7,7 @@ import json
 import requests_mock
 
 from briar_wrapper.models.contacts import Contacts
+from briar_wrapper.models.socket_listener import SocketListener
 
 BASE_HTTP_URL = "http://localhost:7000/v1/contacts/"
 
@@ -96,3 +97,26 @@ def test_get_link(api, request_headers, requests_mock):
                                request_headers=request_headers,
                                text=json.dumps(response))
     assert contacts.get_link() == TEST_LINK
+
+
+def test_watch_signal_added(api, mocker):
+    contacts = Contacts(api)
+    contacts._api.socket_listener = SocketListener(None)
+    contacts._api.socket_listener._highest_signal_id = 136
+
+    assert contacts._api.socket_listener._signals == dict()
+
+    contacts.watch_connections(None)
+
+    expected_signals = {
+        137: {
+            "event": "ContactConnectedEvent",
+            "callback": contacts._handle_connections_callback
+        },
+        138: {
+            "event": "ContactDisconnectedEvent",
+            "callback": contacts._handle_connections_callback
+        }
+    }
+
+    assert contacts._api.socket_listener._signals == expected_signals
-- 
GitLab