1
0

Make sure we can see newly_left from state reset

This commit is contained in:
Eric Eastwood
2024-09-17 22:03:35 -05:00
parent d1b7164c5e
commit 72ccdebb3f
3 changed files with 158 additions and 6 deletions
+6 -4
View File
@@ -271,6 +271,8 @@ class SlidingSyncRoomLists:
missing_newly_left_rooms = (
newly_left_room_map.keys() - room_membership_for_user_map.keys()
)
logger.info("asdf newly_left_room_map: %s", newly_left_room_map.keys())
logger.info("asdf missing_newly_left_rooms: %s", missing_newly_left_rooms)
if missing_newly_left_rooms:
# TODO: It would be nice to avoid these copies
room_membership_for_user_map = dict(room_membership_for_user_map)
@@ -514,6 +516,10 @@ class SlidingSyncRoomLists:
previous_connection_state, from_token, relevant_room_map
)
logger.info(
"asdf room_membership_for_user_map: %s", room_membership_for_user_map
)
return SlidingSyncInterestedRooms(
lists=lists,
relevant_room_map=relevant_room_map,
@@ -1097,10 +1103,6 @@ class SlidingSyncRoomLists:
if membership_change.membership != Membership.JOIN:
has_non_join_event_by_room_id_in_from_to_range[room_id] = True
logger.info(
"asdf last_membership_change_by_room_id_in_from_to_range %s",
last_membership_change_by_room_id_in_from_to_range,
)
# 1) Fixup
#
# 2) We also want to assemble a list of possibly newly joined rooms. Someone
@@ -24,6 +24,7 @@ import synapse.rest.admin
from synapse.api.constants import (
AccountDataTypes,
EventTypes,
JoinRules,
Membership,
)
from synapse.api.room_versions import RoomVersions
@@ -43,6 +44,7 @@ from synapse.util.stringutils import random_string
from tests import unittest
from tests.server import TimedOutException
from tests.test_utils.event_injection import create_event
logger = logging.getLogger(__name__)
@@ -846,3 +848,68 @@ class SlidingSyncTestCase(SlidingSyncBase):
# Make the Sliding Sync request
response_body, _ = self.do_sync(sync_body, tok=user1_tok)
self.assertEqual(response_body["rooms"][room_id1]["initial"], True)
def test_state_reset_room_comes_down_incremental_sync(self) -> None:
"""Test that a room that we were state reset out of comes down
incremental sync"""
user1_id = self.register_user("user1", "pass")
user1_tok = self.login(user1_id, "pass")
user2_id = self.register_user("user2", "pass")
user2_tok = self.login(user2_id, "pass")
room_id1 = self.helper.create_room_as(user2_id, is_public=True, tok=user2_tok)
event_response = self.helper.send(room_id1, "test", tok=user2_tok)
event_id = event_response["event_id"]
self.helper.join(room_id1, user1_id, tok=user1_tok)
sync_body = {
"lists": {
"foo-list": {
"ranges": [[0, 1]],
"required_state": [],
"timeline_limit": 1,
}
}
}
# Make the Sliding Sync request
response_body, from_token = self.do_sync(sync_body, tok=user1_tok)
self.assertEqual(response_body["rooms"][room_id1]["initial"], True)
# Trigger a state reset
join_rule_event, join_rule_context = self.get_success(
create_event(
self.hs,
prev_event_ids=[event_id],
type=EventTypes.JoinRules,
state_key="",
content={"join_rule": JoinRules.INVITE},
sender=user2_id,
room_id=room_id1,
room_version=self.get_success(self.store.get_room_version_id(room_id1)),
)
)
_, join_rule_event_pos, _ = self.get_success(
self.hs.get_storage_controllers().persistence.persist_event(
join_rule_event, join_rule_context
)
)
# FIXME: We're manually busting the cache since
# https://github.com/element-hq/synapse/issues/17368 is not solved yet
self.store._membership_stream_cache.entity_has_changed(
user1_id, join_rule_event_pos.stream
)
users_in_room = self.get_success(self.store.get_users_in_room(room_id1))
self.assertIncludes(set(users_in_room), {user2_id}, exact=True)
# Make another Sliding Sync request (incremental)
response_body, _ = self.do_sync(sync_body, since=from_token, tok=user1_tok)
# TODO: What should we expect here? Probably at least *something*?
print(response_body["rooms"].keys())
print(response_body["rooms"][room_id1])
+85 -2
View File
@@ -27,7 +27,13 @@ from immutabledict import immutabledict
from twisted.test.proto_helpers import MemoryReactor
from synapse.api.constants import Direction, EventTypes, Membership, RelationTypes
from synapse.api.constants import (
Direction,
EventTypes,
Membership,
JoinRules,
RelationTypes,
)
from synapse.api.filtering import Filter
from synapse.crypto.event_signing import add_hashes_and_signatures
from synapse.events import FrozenEventV3
@@ -1154,7 +1160,7 @@ class GetCurrentStateDeltaMembershipChangesForUserTestCase(HomeserverTestCase):
room_id=room_id1,
event_id=None,
event_pos=dummy_state_pos,
membership="leave",
membership=Membership.LEAVE,
sender=None, # user1_id,
prev_event_id=join_response1["event_id"],
prev_event_pos=join_pos1,
@@ -1164,6 +1170,83 @@ class GetCurrentStateDeltaMembershipChangesForUserTestCase(HomeserverTestCase):
],
)
def test_state_reset2(self) -> None:
"""
Test a state reset scenario where the user gets removed from the room (when
there is no corresponding leave event)
"""
user1_id = self.register_user("user1", "pass")
user1_tok = self.login(user1_id, "pass")
user2_id = self.register_user("user2", "pass")
user2_tok = self.login(user2_id, "pass")
room_id1 = self.helper.create_room_as(user2_id, is_public=True, tok=user2_tok)
event_response = self.helper.send(room_id1, "test", tok=user2_tok)
event_id = event_response["event_id"]
user1_join_response = self.helper.join(room_id1, user1_id, tok=user1_tok)
user1_join_pos = self.get_success(
self.store.get_position_for_event(user1_join_response["event_id"])
)
before_reset_token = self.event_sources.get_current_token()
# Trigger a state reset
join_rule_event, join_rule_context = self.get_success(
create_event(
self.hs,
prev_event_ids=[event_id],
type=EventTypes.JoinRules,
state_key="",
content={"join_rule": JoinRules.INVITE},
sender=user2_id,
room_id=room_id1,
room_version=self.get_success(self.store.get_room_version_id(room_id1)),
)
)
_, join_rule_event_pos, _ = self.get_success(
self.hs.get_storage_controllers().persistence.persist_event(
join_rule_event, join_rule_context
)
)
# FIXME: We're manually busting the cache since
# https://github.com/element-hq/synapse/issues/17368 is not solved yet
self.store._membership_stream_cache.entity_has_changed(
user1_id, join_rule_event_pos.stream
)
after_reset_token = self.event_sources.get_current_token()
membership_changes = self.get_success(
self.store.get_current_state_delta_membership_changes_for_user(
user1_id,
from_key=before_reset_token.room_key,
to_key=after_reset_token.room_key,
)
)
# Let the whole diff show on failure
self.maxDiff = None
self.assertEqual(
membership_changes,
[
CurrentStateDeltaMembership(
room_id=room_id1,
event_id=None,
# The position where the state reset happened
event_pos=join_rule_event_pos,
membership=Membership.LEAVE,
sender=None,
prev_event_id=user1_join_response["event_id"],
prev_event_pos=user1_join_pos,
prev_membership="join",
prev_sender=user1_id,
),
],
)
def test_excluded_room_ids(self) -> None:
"""
Test that the `excluded_room_ids` option excludes changes from the specified rooms.