@@ -240,6 +240,7 @@ def _create_remote_invite_room_for_user(
240240 self ,
241241 invitee_user_id : str ,
242242 unsigned_invite_room_state : Optional [List [StrippedStateEvent ]],
243+ invite_room_id : Optional [str ] = None ,
243244 ) -> str :
244245 """
245246 Create a fake invite for a remote room and persist it.
@@ -252,19 +253,23 @@ def _create_remote_invite_room_for_user(
252253 invitee_user_id: The person being invited
253254 unsigned_invite_room_state: List of stripped state events to assist the
254255 receiver in identifying the room.
256+ invite_room_id: Optional remote room ID to be invited to. When unset, we
257+ will generate one.
255258
256259 Returns:
257260 The room ID of the remote invite room
258261 """
259262 store = self .hs .get_datastores ().main
260263
261- invite_room_id = f"!test_room{ self ._remote_invite_count } :remote_server"
264+ if invite_room_id is None :
265+ invite_room_id = f"!test_room{ self ._remote_invite_count } :remote_server"
262266
263267 invite_event_dict = {
264268 "room_id" : invite_room_id ,
265269 "sender" : "@inviter:remote_server" ,
266270 "state_key" : invitee_user_id ,
267- "depth" : 1 ,
271+ # Just keep advancing the depth
272+ "depth" : self ._remote_invite_count ,
268273 "origin_server_ts" : 1 ,
269274 "type" : EventTypes .Member ,
270275 "content" : {"membership" : Membership .INVITE },
@@ -679,6 +684,112 @@ def test_forgotten_up_to_date(self) -> None:
679684 exact = True ,
680685 )
681686
687+ def test_rejoin_forgotten_room (self ) -> None :
688+ """
689+ Make sure we can see a forgotten room again if we rejoin (or any new membership
690+ like an invite) (no longer forgotten)
691+ """
692+ user1_id = self .register_user ("user1" , "pass" )
693+ user1_tok = self .login (user1_id , "pass" )
694+ user2_id = self .register_user ("user2" , "pass" )
695+ user2_tok = self .login (user2_id , "pass" )
696+
697+ room_id = self .helper .create_room_as (user2_id , tok = user2_tok , is_public = True )
698+ # User1 joins the room
699+ self .helper .join (room_id , user1_id , tok = user1_tok )
700+
701+ # Make the Sliding Sync request
702+ sync_body = {
703+ "lists" : {
704+ "foo-list" : {
705+ "ranges" : [[0 , 99 ]],
706+ "required_state" : [],
707+ "timeline_limit" : 0 ,
708+ }
709+ }
710+ }
711+ response_body , from_token = self .do_sync (sync_body , tok = user1_tok )
712+ # We should see the room (like normal)
713+ self .assertIncludes (
714+ set (response_body ["lists" ]["foo-list" ]["ops" ][0 ]["room_ids" ]),
715+ {room_id },
716+ exact = True ,
717+ )
718+
719+ # Leave and forget the room
720+ self .helper .leave (room_id , user1_id , tok = user1_tok )
721+ # User1 forgets the room
722+ channel = self .make_request (
723+ "POST" ,
724+ f"/_matrix/client/r0/rooms/{ room_id } /forget" ,
725+ content = {},
726+ access_token = user1_tok ,
727+ )
728+ self .assertEqual (channel .code , 200 , channel .result )
729+
730+ # Re-join the room
731+ self .helper .join (room_id , user1_id , tok = user1_tok )
732+
733+ # We should see the room again after re-joining
734+ response_body , _ = self .do_sync (sync_body , since = from_token , tok = user1_tok )
735+ self .assertIncludes (
736+ set (response_body ["lists" ]["foo-list" ]["ops" ][0 ]["room_ids" ]),
737+ {room_id },
738+ exact = True ,
739+ )
740+
741+ def test_invited_to_forgotten_remote_room (self ) -> None :
742+ """
743+ Make sure we can see a forgotten room again if we are invited again
744+ (remote/federated out-of-band memberships)
745+ """
746+ user1_id = self .register_user ("user1" , "pass" )
747+ user1_tok = self .login (user1_id , "pass" )
748+
749+ # Create a remote room invite (out-of-band membership)
750+ room_id = self ._create_remote_invite_room_for_user (user1_id , None )
751+
752+ # Make the Sliding Sync request
753+ sync_body = {
754+ "lists" : {
755+ "foo-list" : {
756+ "ranges" : [[0 , 99 ]],
757+ "required_state" : [],
758+ "timeline_limit" : 0 ,
759+ }
760+ }
761+ }
762+ response_body , from_token = self .do_sync (sync_body , tok = user1_tok )
763+ # We should see the room (like normal)
764+ self .assertIncludes (
765+ set (response_body ["lists" ]["foo-list" ]["ops" ][0 ]["room_ids" ]),
766+ {room_id },
767+ exact = True ,
768+ )
769+
770+ # Leave and forget the room
771+ self .helper .leave (room_id , user1_id , tok = user1_tok )
772+ # User1 forgets the room
773+ channel = self .make_request (
774+ "POST" ,
775+ f"/_matrix/client/r0/rooms/{ room_id } /forget" ,
776+ content = {},
777+ access_token = user1_tok ,
778+ )
779+ self .assertEqual (channel .code , 200 , channel .result )
780+
781+ # Get invited to the room again
782+ # self.helper.join(room_id, user1_id, tok=user1_tok)
783+ self ._create_remote_invite_room_for_user (user1_id , None , invite_room_id = room_id )
784+
785+ # We should see the room again after re-joining
786+ response_body , _ = self .do_sync (sync_body , since = from_token , tok = user1_tok )
787+ self .assertIncludes (
788+ set (response_body ["lists" ]["foo-list" ]["ops" ][0 ]["room_ids" ]),
789+ {room_id },
790+ exact = True ,
791+ )
792+
682793 def test_ignored_user_invites_initial_sync (self ) -> None :
683794 """
684795 Make sure we ignore invites if they are from one of the `m.ignored_user_list` on
0 commit comments