summary refs log tree commit diff
path: root/tests/handlers/test_presencelike.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/handlers/test_presencelike.py')
-rw-r--r--tests/handlers/test_presencelike.py250
1 files changed, 250 insertions, 0 deletions
diff --git a/tests/handlers/test_presencelike.py b/tests/handlers/test_presencelike.py
new file mode 100644
index 0000000000..c194e4dd72
--- /dev/null
+++ b/tests/handlers/test_presencelike.py
@@ -0,0 +1,250 @@
+# -*- coding: utf-8 -*-
+"""This file contains tests of the "presence-like" data that is shared between
+presence and profiles; namely, the displayname and avatar_url."""
+
+from twisted.trial import unittest
+from twisted.internet import defer
+
+from mock import Mock, call, ANY
+import logging
+
+from synapse.server import HomeServer
+from synapse.api.constants import PresenceState
+from synapse.handlers.presence import PresenceHandler
+from synapse.handlers.profile import ProfileHandler
+
+
+OFFLINE = PresenceState.OFFLINE
+BUSY = PresenceState.BUSY
+ONLINE = PresenceState.ONLINE
+
+
+logging.getLogger().addHandler(logging.NullHandler())
+
+
+class MockReplication(object):
+    def __init__(self):
+        self.edu_handlers = {}
+
+    def register_edu_handler(self, edu_type, handler):
+        self.edu_handlers[edu_type] = handler
+
+    def received_edu(self, origin, edu_type, content):
+        self.edu_handlers[edu_type](origin, content)
+
+
+class PresenceAndProfileHandlers(object):
+    def __init__(self, hs):
+        self.presence_handler = PresenceHandler(hs)
+        self.profile_handler = ProfileHandler(hs)
+
+
+class PresenceProfilelikeDataTestCase(unittest.TestCase):
+
+    def setUp(self):
+        hs = HomeServer("test",
+                db_pool=None,
+                datastore=Mock(spec=[
+                    "set_presence_state",
+
+                    "set_profile_displayname",
+                ]),
+                handlers=None,
+                http_server=Mock(),
+                http_client=None,
+                replication_layer=MockReplication(),
+            )
+        hs.handlers = PresenceAndProfileHandlers(hs)
+
+        self.datastore = hs.get_datastore()
+
+        self.replication = hs.get_replication_layer()
+        self.replication.send_edu = Mock()
+        self.replication.send_edu.return_value = defer.succeed((200, "OK"))
+
+        def get_profile_displayname(user_localpart):
+            return defer.succeed("Frank")
+        self.datastore.get_profile_displayname = get_profile_displayname
+
+        def get_profile_avatar_url(user_localpart):
+            return defer.succeed("http://foo")
+        self.datastore.get_profile_avatar_url = get_profile_avatar_url
+
+        def get_presence_list(user_localpart, accepted=None):
+            return defer.succeed([
+                {"observed_user_id": "@banana:test"},
+                {"observed_user_id": "@clementine:test"},
+            ])
+        self.datastore.get_presence_list = get_presence_list
+
+        self.handlers = hs.get_handlers()
+
+        self.mock_start = Mock()
+        self.mock_stop = Mock()
+
+        self.mock_update_client = Mock()
+        self.mock_update_client.return_value = defer.succeed(None)
+
+        self.handlers.presence_handler.start_polling_presence = self.mock_start
+        self.handlers.presence_handler.stop_polling_presence = self.mock_stop
+        self.handlers.presence_handler.push_update_to_clients = (
+                self.mock_update_client)
+
+        hs.handlers.room_member_handler = Mock(spec=[
+            "get_rooms_for_user",
+        ])
+        hs.handlers.room_member_handler.get_rooms_for_user = (
+                lambda u: defer.succeed([]))
+
+        # Some local users to test with
+        self.u_apple = hs.parse_userid("@apple:test")
+        self.u_banana = hs.parse_userid("@banana:test")
+        self.u_clementine = hs.parse_userid("@clementine:test")
+
+        # Remote user
+        self.u_potato = hs.parse_userid("@potato:remote")
+
+    @defer.inlineCallbacks
+    def test_set_my_state(self):
+        mocked_set = self.datastore.set_presence_state
+        mocked_set.return_value = defer.succeed({"state": OFFLINE})
+
+        yield self.handlers.presence_handler.set_state(
+                target_user=self.u_apple, auth_user=self.u_apple,
+                state={"state": BUSY, "status_msg": "Away"})
+
+        mocked_set.assert_called_with("apple",
+                {"state": 1, "status_msg": "Away"})
+        self.mock_start.assert_called_with(self.u_apple,
+                state={"state": 1, "status_msg": "Away",
+                       "displayname": "Frank",
+                       "avatar_url": "http://foo"})
+
+    @defer.inlineCallbacks
+    def test_push_local(self):
+        self.datastore.set_presence_state.return_value = defer.succeed(
+                {"state": ONLINE})
+
+        # TODO(paul): Gut-wrenching
+        from synapse.handlers.presence import UserPresenceCache
+        self.handlers.presence_handler._user_cachemap[self.u_apple] = (
+                UserPresenceCache())
+        apple_set = self.handlers.presence_handler._local_pushmap.setdefault(
+                "apple", set())
+        apple_set.add(self.u_banana)
+        apple_set.add(self.u_clementine)
+
+        yield self.handlers.presence_handler.set_state(self.u_apple,
+                self.u_apple, {"state": ONLINE})
+        yield self.handlers.presence_handler.set_state(self.u_banana,
+                self.u_banana, {"state": ONLINE})
+
+        presence = yield self.handlers.presence_handler.get_presence_list(
+                observer_user=self.u_apple, accepted=True)
+
+        self.assertEquals([
+                {"observed_user": self.u_banana, "state": ONLINE,
+                    "displayname": "Frank", "avatar_url": "http://foo"},
+                {"observed_user": self.u_clementine, "state": OFFLINE}],
+            presence)
+
+        self.mock_update_client.assert_has_calls([
+            call(observer_user=self.u_apple,
+                observed_user=self.u_apple,
+                statuscache=ANY), # self-reflection
+            call(observer_user=self.u_banana,
+                observed_user=self.u_apple,
+                statuscache=ANY),
+        ], any_order=True)
+
+        statuscache = self.mock_update_client.call_args[1]["statuscache"]
+        self.assertEquals({"state": ONLINE,
+                           "displayname": "Frank",
+                           "avatar_url": "http://foo"}, statuscache.state)
+
+        self.mock_update_client.reset_mock()
+
+        self.datastore.set_profile_displayname.return_value = defer.succeed(
+                None)
+
+        yield self.handlers.profile_handler.set_displayname(self.u_apple,
+                self.u_apple, "I am an Apple")
+
+        self.mock_update_client.assert_has_calls([
+            call(observer_user=self.u_apple,
+                observed_user=self.u_apple,
+                statuscache=ANY), # self-reflection
+            call(observer_user=self.u_banana,
+                observed_user=self.u_apple,
+                statuscache=ANY),
+        ], any_order=True)
+
+        statuscache = self.mock_update_client.call_args[1]["statuscache"]
+        self.assertEquals({"state": ONLINE,
+                           "displayname": "I am an Apple",
+                           "avatar_url": "http://foo"}, statuscache.state)
+
+    @defer.inlineCallbacks
+    def test_push_remote(self):
+        self.datastore.set_presence_state.return_value = defer.succeed(
+                {"state": ONLINE})
+
+        # TODO(paul): Gut-wrenching
+        from synapse.handlers.presence import UserPresenceCache
+        self.handlers.presence_handler._user_cachemap[self.u_apple] = (
+                UserPresenceCache())
+        apple_set = self.handlers.presence_handler._remote_sendmap.setdefault(
+                "apple", set())
+        apple_set.add(self.u_potato.domain)
+
+        yield self.handlers.presence_handler.set_state(self.u_apple,
+                self.u_apple, {"state": ONLINE})
+
+        self.replication.send_edu.assert_called_with(
+                destination="remote",
+                edu_type="m.presence",
+                content={
+                    "push": [
+                        {"user_id": "@apple:test",
+                         "state": 2,
+                         "displayname": "Frank",
+                         "avatar_url": "http://foo"},
+                    ],
+                },
+        )
+
+    @defer.inlineCallbacks
+    def test_recv_remote(self):
+        # TODO(paul): Gut-wrenching
+        potato_set = self.handlers.presence_handler._remote_recvmap.setdefault(
+                self.u_potato, set())
+        potato_set.add(self.u_apple)
+
+        yield self.replication.received_edu(
+                "remote", "m.presence", {
+                    "push": [
+                        {"user_id": "@potato:remote",
+                         "state": 2,
+                         "displayname": "Frank",
+                         "avatar_url": "http://foo"},
+                    ],
+                }
+        )
+
+        self.mock_update_client.assert_called_with(
+            observer_user=self.u_apple,
+            observed_user=self.u_potato,
+            statuscache=ANY)
+
+        statuscache = self.mock_update_client.call_args[1]["statuscache"]
+        self.assertEquals({"state": ONLINE,
+                           "displayname": "Frank",
+                           "avatar_url": "http://foo"}, statuscache.state)
+
+        state = yield self.handlers.presence_handler.get_state(self.u_potato,
+                self.u_apple)
+
+        self.assertEquals({"state": ONLINE,
+                           "displayname": "Frank",
+                           "avatar_url": "http://foo"},
+                state)