Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Prevent join->join membership transitions changing member count #7977

Merged
merged 10 commits into from
Aug 3, 2020
1 change: 1 addition & 0 deletions changelog.d/7977.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug that caused room membership counts to increase when changing per-room profile information. Introduced in Synapse v1.7.2.
anoadragon453 marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion synapse/handlers/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ async def _handle_deltas(self, deltas):

if membership == prev_membership:
pass # noop
if membership == Membership.JOIN:
elif membership == Membership.JOIN:
room_stats_delta["joined_members"] += 1
elif membership == Membership.INVITE:
room_stats_delta["invited_members"] += 1
Expand Down
31 changes: 31 additions & 0 deletions tests/handlers/test_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,37 @@ def test_send_message_increments_total_events(self):

self.assertEqual(r1stats_post["total_events"] - r1stats_ante["total_events"], 1)

def test_updating_profile_information_does_not_increase_joined_members_count(self):
"""
Check that the joined_members count does not increase when a user changes their
profile information (which is done by sending another join membership event into
the room.
"""
self._perform_background_initial_update()

# Create a user and room
u1 = self.register_user("u1", "pass")
u1token = self.login("u1", "pass")
r1 = self.helper.create_room_as(u1, tok=u1token)

# Get the current room stats
r1stats_ante = self._get_current_stats("room", r1)

# Send a profile update into the room
new_profile = {"displayname": "bob"}
self.helper.change_membership(
r1, u1, u1, "join", extra_data=new_profile, tok=u1token
)

# Get the new room stats
r1stats_post = self._get_current_stats("room", r1)

# Ensure that the user count did not changed
self.assertEqual(r1stats_post["joined_members"], r1stats_ante["joined_members"])
self.assertEqual(
r1stats_post["local_users_in_room"], r1stats_ante["local_users_in_room"]
)

def test_send_state_event_nonoverwriting(self):
"""
When we send a non-overwriting state event, it increments total_events AND current_state_events
Expand Down
24 changes: 23 additions & 1 deletion tests/rest/client/v1/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,28 @@ def leave(self, room=None, user=None, expect_code=200, tok=None):
expect_code=expect_code,
)

def change_membership(self, room, src, targ, membership, tok=None, expect_code=200):
def change_membership(
self,
room: str,
src: str,
targ: str,
membership: str,
extra_data: dict = {},
tok: Optional[str] = None,
expect_code: int = 200,
) -> None:
"""
Send a membership state event into a room.

Args:
room: The ID of the room to send to
src: The mxid of the event sender
targ: The mxid of the event's target. The state key
membership: The type of membership event
extra_data: Extra information to include in the content of the event
tok: The user access token to use
expect_code: The expected HTTP response code
"""
temp_id = self.auth_user_id
self.auth_user_id = src

Expand All @@ -97,6 +118,7 @@ def change_membership(self, room, src, targ, membership, tok=None, expect_code=2
path = path + "?access_token=%s" % tok

data = {"membership": membership}
data.update(extra_data)

request, channel = make_request(
self.hs.get_reactor(), "PUT", path, json.dumps(data).encode("utf8")
Expand Down