@@ -15,7 +15,7 @@ limitations under the License.
1515*/
1616
1717import React from "react" ;
18- import { render , screen , fireEvent } from "@testing-library/react" ;
18+ import { render , screen , fireEvent , act } from "@testing-library/react" ;
1919import { mocked } from "jest-mock" ;
2020import { MatrixClient } from "matrix-js-sdk/src/matrix" ;
2121
@@ -24,8 +24,71 @@ import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
2424import { MetaSpace , SpaceKey } from "../../../../src/stores/spaces" ;
2525import { shouldShowComponent } from "../../../../src/customisations/helpers/UIComponents" ;
2626import { UIComponent } from "../../../../src/settings/UIFeature" ;
27- import { wrapInSdkContext } from "../../../test-utils" ;
27+ import { mkStubRoom , wrapInSdkContext } from "../../../test-utils" ;
2828import { SdkContextClass } from "../../../../src/contexts/SDKContext" ;
29+ import SpaceStore from "../../../../src/stores/spaces/SpaceStore" ;
30+ import DMRoomMap from "../../../../src/utils/DMRoomMap" ;
31+
32+ // DND test utilities based on
33+ // https://github.com/colinrobertbrooks/react-beautiful-dnd-test-utils/issues/18#issuecomment-1373388693
34+ enum Keys {
35+ SPACE = 32 ,
36+ ARROW_LEFT = 37 ,
37+ ARROW_UP = 38 ,
38+ ARROW_RIGHT = 39 ,
39+ ARROW_DOWN = 40 ,
40+ }
41+
42+ enum DragDirection {
43+ LEFT = Keys . ARROW_LEFT ,
44+ UP = Keys . ARROW_UP ,
45+ RIGHT = Keys . ARROW_RIGHT ,
46+ DOWN = Keys . ARROW_DOWN ,
47+ }
48+
49+ // taken from https://github.com/hello-pangea/dnd/blob/main/test/unit/integration/util/controls.ts#L20
50+ const createTransitionEndEvent = ( ) : Event => {
51+ const event = new Event ( "transitionend" , {
52+ bubbles : true ,
53+ cancelable : true ,
54+ } ) as TransitionEvent ;
55+
56+ // cheating and adding property to event as
57+ // TransitionEvent constructor does not exist.
58+ // This is needed because of the following check
59+ // https://github.com/atlassian/react-beautiful-dnd/blob/master/src/view/draggable/draggable.jsx#L130
60+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
61+ ( event as any ) . propertyName = "transform" ;
62+
63+ return event ;
64+ } ;
65+
66+ const pickUp = async ( element : HTMLElement ) => {
67+ fireEvent . keyDown ( element , {
68+ keyCode : Keys . SPACE ,
69+ } ) ;
70+ await screen . findByText ( / Y o u h a v e l i f t e d a n i t e m / i) ;
71+
72+ act ( ( ) => {
73+ jest . runOnlyPendingTimers ( ) ;
74+ } ) ;
75+ } ;
76+
77+ const move = async ( element : HTMLElement , direction : DragDirection ) => {
78+ fireEvent . keyDown ( element , {
79+ keyCode : direction ,
80+ } ) ;
81+ await screen . findByText ( / ( Y o u h a v e m o v e d t h e i t e m | h a s b e e n c o m b i n e d w i t h ) / i) ;
82+ } ;
83+
84+ const drop = async ( element : HTMLElement ) => {
85+ fireEvent . keyDown ( element , {
86+ keyCode : Keys . SPACE ,
87+ } ) ;
88+ fireEvent ( element . parentElement ! , createTransitionEndEvent ( ) ) ;
89+
90+ await screen . findByText ( / Y o u h a v e d r o p p e d t h e i t e m / i) ;
91+ } ;
2992
3093jest . mock ( "../../../../src/stores/spaces/SpaceStore" , ( ) => {
3194 // eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -35,6 +98,10 @@ jest.mock("../../../../src/stores/spaces/SpaceStore", () => {
3598 enabledMetaSpaces : MetaSpace [ ] = [ ] ;
3699 spacePanelSpaces : string [ ] = [ ] ;
37100 activeSpace : SpaceKey = "!space1" ;
101+ getChildSpaces = ( ) => [ ] ;
102+ getNotificationState = ( ) => null ;
103+ setActiveSpace = jest . fn ( ) ;
104+ moveRootSpace = jest . fn ( ) ;
38105 }
39106 return {
40107 instance : new MockSpaceStore ( ) ,
@@ -49,8 +116,12 @@ describe("<SpacePanel />", () => {
49116 const mockClient = {
50117 getUserId : jest . fn ( ) . mockReturnValue ( "@test:test" ) ,
51118 getSafeUserId : jest . fn ( ) . mockReturnValue ( "@test:test" ) ,
119+ mxcUrlToHttp : jest . fn ( ) ,
120+ getRoom : jest . fn ( ) ,
52121 isGuest : jest . fn ( ) ,
53122 getAccountData : jest . fn ( ) ,
123+ on : jest . fn ( ) ,
124+ removeListener : jest . fn ( ) ,
54125 } as unknown as MatrixClient ;
55126 const SpacePanel = wrapInSdkContext ( UnwrappedSpacePanel , SdkContextClass . instance ) ;
56127
@@ -81,4 +152,23 @@ describe("<SpacePanel />", () => {
81152 screen . getByTestId ( "create-space-button" ) ;
82153 } ) ;
83154 } ) ;
155+
156+ it ( "should allow rearranging via drag and drop" , async ( ) => {
157+ ( SpaceStore . instance . spacePanelSpaces as any ) = [
158+ mkStubRoom ( "!room1:server" , "Room 1" , mockClient ) ,
159+ mkStubRoom ( "!room2:server" , "Room 2" , mockClient ) ,
160+ mkStubRoom ( "!room3:server" , "Room 3" , mockClient ) ,
161+ ] ;
162+ DMRoomMap . makeShared ( ) ;
163+ jest . useFakeTimers ( ) ;
164+
165+ const { getByLabelText } = render ( < SpacePanel /> ) ;
166+
167+ const room1 = getByLabelText ( "Room 1" ) ;
168+ await pickUp ( room1 ) ;
169+ await move ( room1 , DragDirection . DOWN ) ;
170+ await drop ( room1 ) ;
171+
172+ expect ( SpaceStore . instance . moveRootSpace ) . toHaveBeenCalledWith ( 0 , 1 ) ;
173+ } ) ;
84174} ) ;
0 commit comments