summary refs log tree commit diff
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2014-09-17 15:05:09 +0100
committerErik Johnston <erik@matrix.org>2014-09-17 15:05:14 +0100
commitb6818fd4d2108543ce86b5d8bf540e74a89cf27e (patch)
tree3b62ea9a09f0cfd2afe4bb238479bcd554af47da
parentBF: edit the actual room name not the displayed room name (which has been com... (diff)
downloadsynapse-b6818fd4d2108543ce86b5d8bf540e74a89cf27e.tar.xz
SYN-40: When a user updates their displayname or avatar update all their join events for all the rooms they are currently in.
-rw-r--r--synapse/handlers/profile.py46
-rw-r--r--tests/handlers/test_presencelike.py11
-rw-r--r--tests/handlers/test_profile.py21
3 files changed, 75 insertions, 3 deletions
diff --git a/synapse/handlers/profile.py b/synapse/handlers/profile.py
index 023d8c0cf2..dab9b03f04 100644
--- a/synapse/handlers/profile.py
+++ b/synapse/handlers/profile.py
@@ -15,9 +15,9 @@
 
 from twisted.internet import defer
 
-from synapse.api.errors import SynapseError, AuthError
-
-from synapse.api.errors import CodeMessageException
+from synapse.api.errors import SynapseError, AuthError, CodeMessageException
+from synapse.api.constants import Membership
+from synapse.api.events.room import RoomMemberEvent
 
 from ._base import BaseHandler
 
@@ -97,6 +97,8 @@ class ProfileHandler(BaseHandler):
             }
         )
 
+        yield self._update_join_states(target_user)
+
     @defer.inlineCallbacks
     def get_avatar_url(self, target_user):
         if target_user.is_mine:
@@ -144,6 +146,8 @@ class ProfileHandler(BaseHandler):
             }
         )
 
+        yield self._update_join_states(target_user)
+
     @defer.inlineCallbacks
     def collect_presencelike_data(self, user, state):
         if not user.is_mine:
@@ -180,3 +184,39 @@ class ProfileHandler(BaseHandler):
             )
 
         defer.returnValue(response)
+
+    @defer.inlineCallbacks
+    def _update_join_states(self, user):
+        if not user.is_mine:
+            return
+
+        joins = yield self.store.get_rooms_for_user_where_membership_is(
+            user.to_string(),
+            [Membership.JOIN],
+        )
+
+        for j in joins:
+            snapshot = yield self.store.snapshot_room(
+                j.room_id, j.state_key, RoomMemberEvent.TYPE,
+                j.state_key
+            )
+
+            content = {
+                "membership": j.content["membership"],
+                "prev": j.content["membership"],
+            }
+
+            yield self.distributor.fire(
+                "collect_presencelike_data", user, content
+            )
+
+            new_event = self.event_factory.create_event(
+                etype=j.type,
+                room_id=j.room_id,
+                state_key=j.state_key,
+                content=content,
+                user_id=j.state_key,
+            )
+
+            yield self.state_handler.handle_new_event(new_event, snapshot)
+            yield self._on_new_room_event(new_event, snapshot)
diff --git a/tests/handlers/test_presencelike.py b/tests/handlers/test_presencelike.py
index 72c55b3667..047752ad68 100644
--- a/tests/handlers/test_presencelike.py
+++ b/tests/handlers/test_presencelike.py
@@ -65,6 +65,8 @@ class PresenceProfilelikeDataTestCase(unittest.TestCase):
                     "is_presence_visible",
 
                     "set_profile_displayname",
+
+                    "get_rooms_for_user_where_membership_is",
                 ]),
                 handlers=None,
                 resource_for_federation=Mock(),
@@ -132,6 +134,10 @@ class PresenceProfilelikeDataTestCase(unittest.TestCase):
         # Remote user
         self.u_potato = hs.parse_userid("@potato:remote")
 
+        self.mock_get_joined = (
+            self.datastore.get_rooms_for_user_where_membership_is
+        )
+
     @defer.inlineCallbacks
     def test_set_my_state(self):
         self.presence_list = [
@@ -152,6 +158,11 @@ class PresenceProfilelikeDataTestCase(unittest.TestCase):
 
     @defer.inlineCallbacks
     def test_push_local(self):
+        def get_joined(*args):
+            return defer.succeed([])
+
+        self.mock_get_joined.side_effect = get_joined
+
         self.presence_list = [
             {"observed_user_id": "@banana:test"},
             {"observed_user_id": "@clementine:test"},
diff --git a/tests/handlers/test_profile.py b/tests/handlers/test_profile.py
index 0a5cebb4cc..ee2be9b6d5 100644
--- a/tests/handlers/test_profile.py
+++ b/tests/handlers/test_profile.py
@@ -22,6 +22,7 @@ from mock import Mock
 from synapse.api.errors import AuthError
 from synapse.server import HomeServer
 from synapse.handlers.profile import ProfileHandler
+from synapse.api.constants import Membership
 
 
 class ProfileHandlers(object):
@@ -50,6 +51,7 @@ class ProfileTestCase(unittest.TestCase):
                     "set_profile_displayname",
                     "get_profile_avatar_url",
                     "set_profile_avatar_url",
+                    "get_rooms_for_user_where_membership_is",
                 ]),
                 handlers=None,
                 resource_for_federation=Mock(),
@@ -65,6 +67,10 @@ class ProfileTestCase(unittest.TestCase):
 
         self.handler = hs.get_handlers().profile_handler
 
+        self.mock_get_joined = (
+            self.datastore.get_rooms_for_user_where_membership_is
+        )
+
         # TODO(paul): Icky signal declarings.. booo
         hs.get_distributor().declare("changed_presencelike_data")
 
@@ -83,8 +89,15 @@ class ProfileTestCase(unittest.TestCase):
         mocked_set = self.datastore.set_profile_displayname
         mocked_set.return_value = defer.succeed(())
 
+        self.mock_get_joined.return_value = defer.succeed([])
+
         yield self.handler.set_displayname(self.frank, self.frank, "Frank Jr.")
 
+        self.mock_get_joined.assert_called_once_with(
+            self.frank.to_string(),
+            [Membership.JOIN]
+        )
+
         mocked_set.assert_called_with("1234ABCD", "Frank Jr.")
 
     @defer.inlineCallbacks
@@ -135,7 +148,15 @@ class ProfileTestCase(unittest.TestCase):
         mocked_set = self.datastore.set_profile_avatar_url
         mocked_set.return_value = defer.succeed(())
 
+        self.mock_get_joined.return_value = defer.succeed([])
+
         yield self.handler.set_avatar_url(self.frank, self.frank,
                 "http://my.server/pic.gif")
 
+        self.mock_get_joined.assert_called_once_with(
+            self.frank.to_string(),
+            [Membership.JOIN]
+        )
+
+
         mocked_set.assert_called_with("1234ABCD", "http://my.server/pic.gif")