diff options
Diffstat (limited to 'tests/handlers/test_presencelike.py')
-rw-r--r-- | tests/handlers/test_presencelike.py | 250 |
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) |