1313# limitations under the License.
1414from typing import Optional
1515
16+ from synapse .api .constants import EventContentFields , EventTypes , RoomTypes
1617from synapse .config .server import DEFAULT_ROOM_VERSION
1718from synapse .rest import admin
1819from synapse .rest .client import login , room , room_upgrade_rest_servlet
20+ from synapse .server import HomeServer
1921
2022from tests import unittest
2123from tests .server import FakeChannel
@@ -29,9 +31,8 @@ class UpgradeRoomTest(unittest.HomeserverTestCase):
2931 room_upgrade_rest_servlet .register_servlets ,
3032 ]
3133
32- def prepare (self , reactor , clock , hs ):
34+ def prepare (self , reactor , clock , hs : "HomeServer" ):
3335 self .store = hs .get_datastore ()
34- self .handler = hs .get_user_directory_handler ()
3536
3637 self .creator = self .register_user ("creator" , "pass" )
3738 self .creator_token = self .login (self .creator , "pass" )
@@ -42,13 +43,18 @@ def prepare(self, reactor, clock, hs):
4243 self .room_id = self .helper .create_room_as (self .creator , tok = self .creator_token )
4344 self .helper .join (self .room_id , self .other , tok = self .other_token )
4445
45- def _upgrade_room (self , token : Optional [str ] = None ) -> FakeChannel :
46+ def _upgrade_room (
47+ self , token : Optional [str ] = None , room_id : Optional [str ] = None
48+ ) -> FakeChannel :
4649 # We never want a cached response.
4750 self .reactor .advance (5 * 60 + 1 )
4851
52+ if room_id is None :
53+ room_id = self .room_id
54+
4955 return self .make_request (
5056 "POST" ,
51- "/_matrix/client/r0/rooms/%s /upgrade" % self . room_id ,
57+ f "/_matrix/client/r0/rooms/{ room_id } /upgrade" ,
5258 # This will upgrade a room to the same version, but that's fine.
5359 content = {"new_version" : DEFAULT_ROOM_VERSION },
5460 access_token = token or self .creator_token ,
@@ -157,3 +163,56 @@ def test_power_levels_tombstone(self):
157163 tok = self .creator_token ,
158164 )
159165 self .assertNotIn (self .other , power_levels ["users" ])
166+
167+ def test_space (self ):
168+ """Test upgrading a space."""
169+
170+ # Create a space.
171+ space_id = self .helper .create_room_as (
172+ self .creator ,
173+ tok = self .creator_token ,
174+ extra_content = {
175+ "creation_content" : {EventContentFields .ROOM_TYPE : RoomTypes .SPACE }
176+ },
177+ )
178+
179+ # Add the room as a child room.
180+ self .helper .send_state (
181+ space_id ,
182+ event_type = EventTypes .SpaceChild ,
183+ body = {"via" : [self .hs .hostname ]},
184+ tok = self .creator_token ,
185+ state_key = self .room_id ,
186+ )
187+
188+ # Also add a room that was removed.
189+ old_room_id = "!notaroom:" + self .hs .hostname
190+ self .helper .send_state (
191+ space_id ,
192+ event_type = EventTypes .SpaceChild ,
193+ body = {},
194+ tok = self .creator_token ,
195+ state_key = old_room_id ,
196+ )
197+
198+ # Upgrade the room!
199+ channel = self ._upgrade_room (room_id = space_id )
200+ self .assertEquals (200 , channel .code , channel .result )
201+ self .assertIn ("replacement_room" , channel .json_body )
202+
203+ new_space_id = channel .json_body ["replacement_room" ]
204+
205+ state_ids = self .get_success (self .store .get_current_state_ids (new_space_id ))
206+
207+ # Ensure the new room is still a space.
208+ create_event = self .get_success (
209+ self .store .get_event (state_ids [(EventTypes .Create , "" )])
210+ )
211+ self .assertEqual (
212+ create_event .content .get (EventContentFields .ROOM_TYPE ), RoomTypes .SPACE
213+ )
214+
215+ # The child link should have been copied over.
216+ self .assertIn ((EventTypes .SpaceChild , self .room_id ), state_ids )
217+ # The child that was removed should not be copied over.
218+ self .assertNotIn ((EventTypes .SpaceChild , old_room_id ), state_ids )
0 commit comments