diff --git a/synapse/handlers/sliding_sync/room_lists.py b/synapse/handlers/sliding_sync/room_lists.py index c3e0f40ccc..4bdf2543bd 100644 --- a/synapse/handlers/sliding_sync/room_lists.py +++ b/synapse/handlers/sliding_sync/room_lists.py @@ -144,6 +144,8 @@ class SlidingSyncInterestedRooms: _interested_ in (in a pure sense), even if these rooms are omitted from the current window (which is, in a sense, just a computational optimisation). + It also includes the server announcement rooms left out of the lists for + now, so that their updates are recorded until they are listed again. """ room_membership_for_user_map: Mapping[str, RoomsForUserType] @@ -769,7 +771,7 @@ class SlidingSyncRoomLists: lists=lists, relevant_room_map=relevant_room_map, relevant_rooms_to_send_map=relevant_rooms_to_send_map, - all_rooms=all_rooms, + all_rooms=all_rooms | hidden_room_ids, room_membership_for_user_map=room_membership_for_user_map, newly_joined_rooms=newly_joined_room_ids, newly_left_rooms=newly_left_room_map.keys() @@ -972,7 +974,7 @@ class SlidingSyncRoomLists: lists=lists, relevant_room_map=relevant_room_map, relevant_rooms_to_send_map=relevant_rooms_to_send_map, - all_rooms=all_rooms, + all_rooms=all_rooms | hidden_room_ids, room_membership_for_user_map=room_membership_for_user_map, newly_joined_rooms=newly_joined_room_ids, newly_left_rooms=newly_left_room_ids - server_announcement_room_map.keys(), diff --git a/tests/rest/client/sliding_sync/test_server_announcements.py b/tests/rest/client/sliding_sync/test_server_announcements.py index c4b21cf599..fb648cd7dc 100644 --- a/tests/rest/client/sliding_sync/test_server_announcements.py +++ b/tests/rest/client/sliding_sync/test_server_announcements.py @@ -333,6 +333,34 @@ class SlidingSyncServerAnnouncementsTestCase(SlidingSyncBase): self._assert_not_delivered(response) + def test_removed_member_room_changed_while_left_out(self) -> None: + """A member removed from the configured senders before anything was + announced gets the room's new name with the first announcement, when the + name changed while the room was left out of their lists. + """ + sync_body = self._sync_body(timeline_limit=5) + _, pos = self.do_sync(sync_body, tok=self.former_tok) + self._remove_former() + _, pos = self.do_sync(sync_body, since=pos, tok=self.former_tok) + self.config.rooms = [attr.evolve(self.config.rooms[0], room_name="New name")] + self.get_success(self.handler.reconcile_rooms()) + response, pos = self.do_sync(sync_body, since=pos, tok=self.former_tok) + self._assert_not_delivered(response) + self._announce("hello") + + response, _ = self.do_sync(sync_body, since=pos, tok=self.former_tok) + + room = response["rooms"][self.room_id] + self.assertEqual(room.get("name"), "New name") + self.assertEqual( + [ + event["content"]["name"] + for event in room.get("required_state", []) + if event["type"] == EventTypes.Name + ], + ["New name"], + ) + def test_removed_member_existing_connection(self) -> None: """A member removed from the configured senders while their connection is open gets the synthetic join instead of their kick, even before anything