@@ -16,7 +16,7 @@ limitations under the License.
1616
1717import React from "react" ;
1818import { mocked } from "jest-mock" ;
19- import { render } from "@testing-library/react" ;
19+ import { fireEvent , render , screen , waitFor , waitForElementToBeRemoved } from "@testing-library/react" ;
2020import { MatrixClient } from "matrix-js-sdk/src/client" ;
2121import { Room } from "matrix-js-sdk/src/models/room" ;
2222import { RoomHierarchy } from "matrix-js-sdk/src/room-hierarchy" ;
@@ -25,7 +25,7 @@ import { IHierarchyRoom } from "matrix-js-sdk/src/@types/spaces";
2525import { MatrixClientPeg } from "../../../src/MatrixClientPeg" ;
2626import { mkStubRoom , stubClient } from "../../test-utils" ;
2727import dispatcher from "../../../src/dispatcher/dispatcher" ;
28- import { HierarchyLevel , showRoom , toLocalRoom } from "../../../src/components/structures/SpaceHierarchy" ;
28+ import SpaceHierarchy , { showRoom , toLocalRoom } from "../../../src/components/structures/SpaceHierarchy" ;
2929import { Action } from "../../../src/dispatcher/actions" ;
3030import MatrixClientContext from "../../../src/contexts/MatrixClientContext" ;
3131import DMRoomMap from "../../../src/utils/DMRoomMap" ;
@@ -158,7 +158,18 @@ describe("SpaceHierarchy", () => {
158158 } ) ;
159159 } ) ;
160160
161- describe ( "<HierarchyLevel />" , ( ) => {
161+ describe ( "<SpaceHierarchy />" , ( ) => {
162+ beforeEach ( ( ) => {
163+ // IntersectionObserver isn't available in test environment
164+ const mockIntersectionObserver = jest . fn ( ) ;
165+ mockIntersectionObserver . mockReturnValue ( {
166+ observe : ( ) => null ,
167+ unobserve : ( ) => null ,
168+ disconnect : ( ) => null ,
169+ } ) ;
170+ window . IntersectionObserver = mockIntersectionObserver ;
171+ } ) ;
172+
162173 stubClient ( ) ;
163174 const client = MatrixClientPeg . get ( ) ;
164175
@@ -167,55 +178,123 @@ describe("SpaceHierarchy", () => {
167178 } as unknown as DMRoomMap ;
168179 jest . spyOn ( DMRoomMap , "shared" ) . mockReturnValue ( dmRoomMap ) ;
169180
170- const root = mkStubRoom ( "room-id-1" , "Room 1" , client ) ;
171- const room1 = mkStubRoom ( "room-id-2" , "Room 2" , client ) ;
172- const room2 = mkStubRoom ( "room-id-3" , "Room 3" , client ) ;
181+ const root = mkStubRoom ( "space-id-1" , "Space 1" , client ) ;
182+ const room1 = mkStubRoom ( "room-id-2" , "Room 1" , client ) ;
183+ const room2 = mkStubRoom ( "room-id-3" , "Room 2" , client ) ;
184+ const space1 = mkStubRoom ( "space-id-4" , "Space 2" , client ) ;
185+ const room3 = mkStubRoom ( "room-id-5" , "Room 3" , client ) ;
186+ mocked ( client . getRooms ) . mockReturnValue ( [ root ] ) ;
187+ mocked ( client . getRoom ) . mockImplementation (
188+ ( roomId ) => client . getRooms ( ) . find ( ( room ) => room . roomId === roomId ) ?? null ,
189+ ) ;
190+ [ room1 , room2 , space1 , room3 ] . forEach ( ( r ) => mocked ( r . getMyMembership ) . mockReturnValue ( "leave" ) ) ;
173191
174- const hierarchyRoot = {
192+ const hierarchyRoot : IHierarchyRoom = {
175193 room_id : root . roomId ,
176194 num_joined_members : 1 ,
195+ room_type : "m.space" ,
177196 children_state : [
178197 {
179198 state_key : room1 . roomId ,
180199 content : { order : "1" } ,
200+ origin_server_ts : 111 ,
201+ type : "m.space.child" ,
202+ sender : "@other:server" ,
181203 } ,
182204 {
183205 state_key : room2 . roomId ,
184206 content : { order : "2" } ,
207+ origin_server_ts : 111 ,
208+ type : "m.space.child" ,
209+ sender : "@other:server" ,
210+ } ,
211+ {
212+ state_key : space1 . roomId ,
213+ content : { order : "3" } ,
214+ origin_server_ts : 111 ,
215+ type : "m.space.child" ,
216+ sender : "@other:server" ,
185217 } ,
186218 ] ,
187- } as IHierarchyRoom ;
188- const hierarchyRoom1 = { room_id : room1 . roomId , num_joined_members : 2 } as IHierarchyRoom ;
189- const hierarchyRoom2 = { room_id : root . roomId , num_joined_members : 3 } as IHierarchyRoom ;
190-
191- const roomHierarchy = {
192- roomMap : new Map ( [
193- [ root . roomId , hierarchyRoot ] ,
194- [ room1 . roomId , hierarchyRoom1 ] ,
195- [ room2 . roomId , hierarchyRoom2 ] ,
196- ] ) ,
197- isSuggested : jest . fn ( ) ,
198- } as unknown as RoomHierarchy ;
199-
200- it ( "renders" , ( ) => {
201- const defaultProps = {
202- root : hierarchyRoot ,
203- roomSet : new Set ( [ hierarchyRoom1 , hierarchyRoom2 ] ) ,
204- hierarchy : roomHierarchy ,
205- parents : new Set < string > ( ) ,
206- selectedMap : new Map < string , Set < string > > ( ) ,
207- onViewRoomClick : jest . fn ( ) ,
208- onJoinRoomClick : jest . fn ( ) ,
209- onToggleClick : jest . fn ( ) ,
210- } ;
211- const getComponent = ( props = { } ) : React . ReactElement => (
212- < MatrixClientContext . Provider value = { client } >
213- < HierarchyLevel { ...defaultProps } { ...props } /> ;
214- </ MatrixClientContext . Provider >
215- ) ;
216-
217- const { container } = render ( getComponent ( ) ) ;
218- expect ( container ) . toMatchSnapshot ( ) ;
219+ world_readable : true ,
220+ guest_can_join : true ,
221+ } ;
222+ const hierarchyRoom1 : IHierarchyRoom = {
223+ room_id : room1 . roomId ,
224+ num_joined_members : 2 ,
225+ children_state : [ ] ,
226+ world_readable : true ,
227+ guest_can_join : true ,
228+ } ;
229+ const hierarchyRoom2 : IHierarchyRoom = {
230+ room_id : room2 . roomId ,
231+ num_joined_members : 3 ,
232+ children_state : [ ] ,
233+ world_readable : true ,
234+ guest_can_join : true ,
235+ } ;
236+ const hierarchyRoom3 : IHierarchyRoom = {
237+ name : "Nested room" ,
238+ room_id : room3 . roomId ,
239+ num_joined_members : 3 ,
240+ children_state : [ ] ,
241+ world_readable : true ,
242+ guest_can_join : true ,
243+ } ;
244+ const hierarchySpace1 : IHierarchyRoom = {
245+ room_id : space1 . roomId ,
246+ name : "Nested space" ,
247+ num_joined_members : 1 ,
248+ room_type : "m.space" ,
249+ children_state : [
250+ {
251+ state_key : room3 . roomId ,
252+ content : { order : "1" } ,
253+ origin_server_ts : 111 ,
254+ type : "m.space.child" ,
255+ sender : "@other:server" ,
256+ } ,
257+ ] ,
258+ world_readable : true ,
259+ guest_can_join : true ,
260+ } ;
261+
262+ mocked ( client . getRoomHierarchy ) . mockResolvedValue ( {
263+ rooms : [ hierarchyRoot , hierarchyRoom1 , hierarchyRoom2 , hierarchySpace1 , hierarchyRoom3 ] ,
264+ } ) ;
265+
266+ const defaultProps = {
267+ space : root ,
268+ showRoom : jest . fn ( ) ,
269+ } ;
270+ const getComponent = ( props = { } ) : React . ReactElement => (
271+ < MatrixClientContext . Provider value = { client } >
272+ < SpaceHierarchy { ...defaultProps } { ...props } /> ;
273+ </ MatrixClientContext . Provider >
274+ ) ;
275+
276+ it ( "renders" , async ( ) => {
277+ const { asFragment } = render ( getComponent ( ) ) ;
278+ // Wait for spinners to go away
279+ await waitForElementToBeRemoved ( screen . getAllByRole ( "progressbar" ) ) ;
280+ expect ( asFragment ( ) ) . toMatchSnapshot ( ) ;
281+ } ) ;
282+
283+ it ( "should join subspace when joining nested room" , async ( ) => {
284+ mocked ( client . joinRoom ) . mockResolvedValue ( { } as Room ) ;
285+
286+ const { getByText } = render ( getComponent ( ) ) ;
287+ // Wait for spinners to go away
288+ await waitForElementToBeRemoved ( screen . getAllByRole ( "progressbar" ) ) ;
289+ const button = getByText ( "Nested room" ) ! . closest ( "li" ) ! . querySelector ( ".mx_AccessibleButton_kind_primary" ) ! ;
290+ fireEvent . click ( button ) ;
291+
292+ await waitFor ( ( ) => {
293+ expect ( client . joinRoom ) . toHaveBeenCalledTimes ( 2 ) ;
294+ } ) ;
295+ // Joins subspace
296+ expect ( client . joinRoom ) . toHaveBeenCalledWith ( space1 . roomId , expect . any ( Object ) ) ;
297+ expect ( client . joinRoom ) . toHaveBeenCalledWith ( room3 . roomId , expect . any ( Object ) ) ;
219298 } ) ;
220299 } ) ;
221300} ) ;
0 commit comments