SYN-40: When a user updates their displayname or avatar update all their join events for all the rooms they are currently in.

This commit is contained in:
Erik Johnston 2014-09-17 15:05:09 +01:00
parent fe7af80198
commit b6818fd4d2
3 changed files with 75 additions and 3 deletions

View file

@ -15,9 +15,9 @@
from twisted.internet import defer from twisted.internet import defer
from synapse.api.errors import SynapseError, AuthError from synapse.api.errors import SynapseError, AuthError, CodeMessageException
from synapse.api.constants import Membership
from synapse.api.errors import CodeMessageException from synapse.api.events.room import RoomMemberEvent
from ._base import BaseHandler from ._base import BaseHandler
@ -97,6 +97,8 @@ class ProfileHandler(BaseHandler):
} }
) )
yield self._update_join_states(target_user)
@defer.inlineCallbacks @defer.inlineCallbacks
def get_avatar_url(self, target_user): def get_avatar_url(self, target_user):
if target_user.is_mine: if target_user.is_mine:
@ -144,6 +146,8 @@ class ProfileHandler(BaseHandler):
} }
) )
yield self._update_join_states(target_user)
@defer.inlineCallbacks @defer.inlineCallbacks
def collect_presencelike_data(self, user, state): def collect_presencelike_data(self, user, state):
if not user.is_mine: if not user.is_mine:
@ -180,3 +184,39 @@ class ProfileHandler(BaseHandler):
) )
defer.returnValue(response) 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)

View file

@ -65,6 +65,8 @@ class PresenceProfilelikeDataTestCase(unittest.TestCase):
"is_presence_visible", "is_presence_visible",
"set_profile_displayname", "set_profile_displayname",
"get_rooms_for_user_where_membership_is",
]), ]),
handlers=None, handlers=None,
resource_for_federation=Mock(), resource_for_federation=Mock(),
@ -132,6 +134,10 @@ class PresenceProfilelikeDataTestCase(unittest.TestCase):
# Remote user # Remote user
self.u_potato = hs.parse_userid("@potato:remote") self.u_potato = hs.parse_userid("@potato:remote")
self.mock_get_joined = (
self.datastore.get_rooms_for_user_where_membership_is
)
@defer.inlineCallbacks @defer.inlineCallbacks
def test_set_my_state(self): def test_set_my_state(self):
self.presence_list = [ self.presence_list = [
@ -152,6 +158,11 @@ class PresenceProfilelikeDataTestCase(unittest.TestCase):
@defer.inlineCallbacks @defer.inlineCallbacks
def test_push_local(self): def test_push_local(self):
def get_joined(*args):
return defer.succeed([])
self.mock_get_joined.side_effect = get_joined
self.presence_list = [ self.presence_list = [
{"observed_user_id": "@banana:test"}, {"observed_user_id": "@banana:test"},
{"observed_user_id": "@clementine:test"}, {"observed_user_id": "@clementine:test"},

View file

@ -22,6 +22,7 @@ from mock import Mock
from synapse.api.errors import AuthError from synapse.api.errors import AuthError
from synapse.server import HomeServer from synapse.server import HomeServer
from synapse.handlers.profile import ProfileHandler from synapse.handlers.profile import ProfileHandler
from synapse.api.constants import Membership
class ProfileHandlers(object): class ProfileHandlers(object):
@ -50,6 +51,7 @@ class ProfileTestCase(unittest.TestCase):
"set_profile_displayname", "set_profile_displayname",
"get_profile_avatar_url", "get_profile_avatar_url",
"set_profile_avatar_url", "set_profile_avatar_url",
"get_rooms_for_user_where_membership_is",
]), ]),
handlers=None, handlers=None,
resource_for_federation=Mock(), resource_for_federation=Mock(),
@ -65,6 +67,10 @@ class ProfileTestCase(unittest.TestCase):
self.handler = hs.get_handlers().profile_handler 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 # TODO(paul): Icky signal declarings.. booo
hs.get_distributor().declare("changed_presencelike_data") hs.get_distributor().declare("changed_presencelike_data")
@ -83,8 +89,15 @@ class ProfileTestCase(unittest.TestCase):
mocked_set = self.datastore.set_profile_displayname mocked_set = self.datastore.set_profile_displayname
mocked_set.return_value = defer.succeed(()) 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.") 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.") mocked_set.assert_called_with("1234ABCD", "Frank Jr.")
@defer.inlineCallbacks @defer.inlineCallbacks
@ -135,7 +148,15 @@ class ProfileTestCase(unittest.TestCase):
mocked_set = self.datastore.set_profile_avatar_url mocked_set = self.datastore.set_profile_avatar_url
mocked_set.return_value = defer.succeed(()) mocked_set.return_value = defer.succeed(())
self.mock_get_joined.return_value = defer.succeed([])
yield self.handler.set_avatar_url(self.frank, self.frank, yield self.handler.set_avatar_url(self.frank, self.frank,
"http://my.server/pic.gif") "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") mocked_set.assert_called_with("1234ABCD", "http://my.server/pic.gif")