@@ -7,111 +7,139 @@ Please see LICENSE files in the repository root for full details.
7
7
*/
8
8
9
9
import React from "react" ;
10
- import { EventTimeline , MatrixEvent , Room , RoomMember } from "matrix-js-sdk/src/matrix" ;
11
- import { render , RenderOptions } from "jest-matrix-react" ;
10
+ import { MatrixClient , MatrixEvent , Room , RoomMember } from "matrix-js-sdk/src/matrix" ;
11
+ import { render , screen , act } from "jest-matrix-react" ;
12
+ import userEvent from "@testing-library/user-event" ;
13
+ import { waitFor } from "@testing-library/dom" ;
12
14
13
- import { MatrixClientPeg } from "../../../../../src/MatrixClientPeg" ;
14
15
import SettingsStore from "../../../../../src/settings/SettingsStore" ;
15
- import MatrixClientContext from "../../../../../src/contexts/MatrixClientContext" ;
16
- import { _t } from "../../../../../src/languageHandler" ;
17
16
import { ShareDialog } from "../../../../../src/components/views/dialogs/ShareDialog" ;
18
17
import { UIFeature } from "../../../../../src/settings/UIFeature" ;
19
- import { stubClient } from "../../../../test-utils" ;
20
- jest . mock ( "../../../../../src/utils/ShieldUtils" ) ;
21
-
22
- function getWrapper ( ) : RenderOptions {
23
- return {
24
- wrapper : ( { children } ) => (
25
- < MatrixClientContext . Provider value = { MatrixClientPeg . safeGet ( ) } > { children } </ MatrixClientContext . Provider >
26
- ) ,
27
- } ;
28
- }
18
+ import { stubClient , withClientContextRenderOptions } from "../../../../test-utils" ;
19
+ import * as StringsModule from "../../../../../src/utils/strings" ;
20
+ import { RoomPermalinkCreator } from "../../../../../src/utils/permalinks/Permalinks.ts" ;
29
21
30
22
describe ( "ShareDialog" , ( ) => {
23
+ let client : MatrixClient ;
31
24
let room : Room ;
32
-
33
- const ROOM_ID = "!1:example.org" ;
25
+ const copyTextFunc = jest . fn ( ) ;
34
26
35
27
beforeEach ( async ( ) => {
36
- stubClient ( ) ;
37
- room = new Room ( ROOM_ID , MatrixClientPeg . get ( ) ! , "@alice:example.org" ) ;
28
+ client = stubClient ( ) ;
29
+ room = new Room ( "!1:example.org" , client , "@alice:example.org" ) ;
30
+ jest . spyOn ( StringsModule , "copyPlaintext" ) . mockImplementation ( copyTextFunc ) ;
38
31
} ) ;
39
32
40
33
afterEach ( ( ) => {
41
34
jest . restoreAllMocks ( ) ;
35
+ copyTextFunc . mockClear ( ) ;
42
36
} ) ;
43
37
44
- it ( "renders room share dialog" , ( ) => {
45
- const { container : withoutEvents } = render ( < ShareDialog target = { room } onFinished = { jest . fn ( ) } /> , getWrapper ( ) ) ;
46
- expect ( withoutEvents ) . toHaveTextContent ( _t ( "share|title_room" ) ) ;
38
+ function renderComponent ( target : Room | RoomMember | URL ) {
39
+ return render ( < ShareDialog target = { target } onFinished = { jest . fn ( ) } /> , withClientContextRenderOptions ( client ) ) ;
40
+ }
41
+
42
+ const getUrl = ( ) => new URL ( "https://matrix.org/" ) ;
43
+ const getRoomMember = ( ) => new RoomMember ( room . roomId , "@alice:example.org" ) ;
44
+
45
+ test . each ( [
46
+ { name : "an URL" , title : "Share Link" , url : "https://matrix.org/" , getTarget : getUrl } ,
47
+ {
48
+ name : "a room member" ,
49
+ title : "Share User" ,
50
+ url : "https://matrix.to/#/@alice:example.org" ,
51
+ getTarget : getRoomMember ,
52
+ } ,
53
+ ] ) ( "should render a share dialog for $name" , async ( { title, url, getTarget } ) => {
54
+ const { asFragment } = renderComponent ( getTarget ( ) ) ;
55
+
56
+ expect ( screen . getByRole ( "heading" , { name : title } ) ) . toBeInTheDocument ( ) ;
57
+ expect ( screen . getByText ( url ) ) . toBeInTheDocument ( ) ;
58
+ expect ( asFragment ( ) ) . toMatchSnapshot ( ) ;
47
59
48
- jest . spyOn ( room , "getLiveTimeline" ) . mockReturnValue ( { getEvents : ( ) => [ { } as MatrixEvent ] } as EventTimeline ) ;
49
- const { container : withEvents } = render ( < ShareDialog target = { room } onFinished = { jest . fn ( ) } /> , getWrapper ( ) ) ;
50
- expect ( withEvents ) . toHaveTextContent ( _t ( "share|permalink_most_recent" ) ) ;
60
+ await userEvent . click ( screen . getByRole ( "button" , { name : "Copy link" } ) ) ;
61
+ expect ( copyTextFunc ) . toHaveBeenCalledWith ( url ) ;
51
62
} ) ;
52
63
53
- it ( "renders user share dialog" , ( ) => {
54
- mockRoomMembers ( room , 1 ) ;
55
- const { container } = render (
56
- < ShareDialog target = { room . getJoinedMembers ( ) [ 0 ] } onFinished = { jest . fn ( ) } /> ,
57
- getWrapper ( ) ,
58
- ) ;
59
- expect ( container ) . toHaveTextContent ( _t ( "share|title_user" ) ) ;
64
+ it ( "should render a share dialog for a room" , async ( ) => {
65
+ const expectedURL = "https://matrix.to/#/!1:example.org" ;
66
+ jest . spyOn ( room . getLiveTimeline ( ) , "getEvents" ) . mockReturnValue ( [ new MatrixEvent ( { event_id : "!eventId" } ) ] ) ;
67
+
68
+ const { asFragment } = renderComponent ( room ) ;
69
+ expect ( screen . getByRole ( "heading" , { name : "Share Room" } ) ) . toBeInTheDocument ( ) ;
70
+ expect ( screen . getByText ( expectedURL ) ) . toBeInTheDocument ( ) ;
71
+ expect ( screen . getByRole ( "checkbox" , { name : "Link to most recent message" } ) ) . toBeInTheDocument ( ) ;
72
+ expect ( asFragment ( ) ) . toMatchSnapshot ( ) ;
73
+
74
+ await userEvent . click ( screen . getByRole ( "button" , { name : "Copy link" } ) ) ;
75
+ expect ( copyTextFunc ) . toHaveBeenCalledWith ( expectedURL ) ;
76
+
77
+ // Click on the checkbox to link to the most recent message
78
+ await userEvent . click ( screen . getByRole ( "checkbox" , { name : "Link to most recent message" } ) ) ;
79
+ const newExpectedURL = "https://matrix.to/#/!1:example.org/!eventId" ;
80
+ expect ( screen . getByText ( newExpectedURL ) ) . toBeInTheDocument ( ) ;
60
81
} ) ;
61
82
62
- it ( "renders link share dialog" , ( ) => {
63
- mockRoomMembers ( room , 1 ) ;
64
- const { container } = render (
65
- < ShareDialog target = { new URL ( "https://matrix.org" ) } onFinished = { jest . fn ( ) } /> ,
66
- getWrapper ( ) ,
83
+ it ( "should render a share dialog for a matrix event" , async ( ) => {
84
+ const matrixEvent = new MatrixEvent ( { event_id : "!eventId" } ) ;
85
+ const permalinkCreator = new RoomPermalinkCreator ( room ) ;
86
+ const expectedURL = "https://matrix.to/#/!1:example.org/!eventId" ;
87
+
88
+ const { asFragment } = render (
89
+ < ShareDialog target = { matrixEvent } permalinkCreator = { permalinkCreator } onFinished = { jest . fn ( ) } /> ,
90
+ withClientContextRenderOptions ( client ) ,
67
91
) ;
68
- expect ( container ) . toHaveTextContent ( _t ( "share|title_link" ) ) ;
92
+ expect ( screen . getByRole ( "heading" , { name : "Share Room Message" } ) ) . toBeInTheDocument ( ) ;
93
+ expect ( screen . getByText ( expectedURL ) ) . toBeInTheDocument ( ) ;
94
+ expect ( screen . getByRole ( "checkbox" , { name : "Link to selected message" } ) ) . toBeChecked ( ) ;
95
+ expect ( asFragment ( ) ) . toMatchSnapshot ( ) ;
96
+
97
+ await userEvent . click ( screen . getByRole ( "button" , { name : "Copy link" } ) ) ;
98
+ expect ( copyTextFunc ) . toHaveBeenCalledWith ( expectedURL ) ;
99
+
100
+ // Click on the checkbox to link to the room
101
+ await userEvent . click ( screen . getByRole ( "checkbox" , { name : "Link to selected message" } ) ) ;
102
+ expect ( screen . getByText ( "https://matrix.to/#/!1:example.org" ) ) . toBeInTheDocument ( ) ;
103
+ } ) ;
104
+
105
+ it ( "should change the copy button text when clicked" , async ( ) => {
106
+ jest . useFakeTimers ( ) ;
107
+ const user = userEvent . setup ( { advanceTimers : jest . advanceTimersByTime } ) ;
108
+ // To not be bother with rtl warnings about QR code state update
109
+ jest . spyOn ( SettingsStore , "getValue" ) . mockReturnValue ( false ) ;
110
+
111
+ renderComponent ( room ) ;
112
+ await user . click ( screen . getByRole ( "button" , { name : "Copy link" } ) ) ;
113
+ // Move after `copyPlaintext`
114
+ await jest . advanceTimersToNextTimerAsync ( ) ;
115
+ expect ( screen . getByRole ( "button" , { name : "Link copied" } ) ) . toBeInTheDocument ( ) ;
116
+
117
+ // 2 sec after the button should be back to normal
118
+ act ( ( ) => jest . advanceTimersByTime ( 2000 ) ) ;
119
+ await waitFor ( ( ) => expect ( screen . getByRole ( "button" , { name : "Copy link" } ) ) . toBeInTheDocument ( ) ) ;
69
120
} ) ;
70
121
71
- it ( "renders the QR code if configured " , ( ) => {
122
+ it ( "should not render the QR code if disabled " , ( ) => {
72
123
const originalGetValue = SettingsStore . getValue ;
73
124
jest . spyOn ( SettingsStore , "getValue" ) . mockImplementation ( ( feature ) => {
74
- if ( feature === UIFeature . ShareQRCode ) return true ;
125
+ if ( feature === UIFeature . ShareQRCode ) return false ;
75
126
return originalGetValue ( feature ) ;
76
127
} ) ;
77
- const { container } = render ( < ShareDialog target = { room } onFinished = { jest . fn ( ) } /> , getWrapper ( ) ) ;
78
- const qrCodesVisible = container . getElementsByClassName ( "mx_ShareDialog_qrcode_container" ) . length > 0 ;
79
- expect ( qrCodesVisible ) . toBe ( true ) ;
128
+
129
+ const { asFragment } = renderComponent ( room ) ;
130
+ expect ( screen . queryByRole ( "img" , { name : "QR code" } ) ) . toBeNull ( ) ;
131
+ expect ( asFragment ( ) ) . toMatchSnapshot ( ) ;
80
132
} ) ;
81
133
82
- it ( "renders the social button if configured " , ( ) => {
134
+ it ( "should not render the socials if disabled " , ( ) => {
83
135
const originalGetValue = SettingsStore . getValue ;
84
136
jest . spyOn ( SettingsStore , "getValue" ) . mockImplementation ( ( feature ) => {
85
- if ( feature === UIFeature . ShareSocial ) return true ;
137
+ if ( feature === UIFeature . ShareSocial ) return false ;
86
138
return originalGetValue ( feature ) ;
87
139
} ) ;
88
- const { container } = render ( < ShareDialog target = { room } onFinished = { jest . fn ( ) } /> , getWrapper ( ) ) ;
89
- const qrCodesVisible = container . getElementsByClassName ( "mx_ShareDialog_social_container" ) . length > 0 ;
90
- expect ( qrCodesVisible ) . toBe ( true ) ;
91
- } ) ;
92
- it ( "renders custom title and subtitle" , ( ) => {
93
- const { container } = render (
94
- < ShareDialog
95
- target = { room }
96
- customTitle = "test_title_123"
97
- subtitle = "custom_subtitle_1234"
98
- onFinished = { jest . fn ( ) }
99
- /> ,
100
- getWrapper ( ) ,
101
- ) ;
102
- expect ( container ) . toHaveTextContent ( "test_title_123" ) ;
103
- expect ( container ) . toHaveTextContent ( "custom_subtitle_1234" ) ;
140
+
141
+ const { asFragment } = renderComponent ( room ) ;
142
+ expect ( screen . queryByRole ( "link" , { name : "Reddit" } ) ) . toBeNull ( ) ;
143
+ expect ( asFragment ( ) ) . toMatchSnapshot ( ) ;
104
144
} ) ;
105
145
} ) ;
106
- /**
107
- *
108
- * @param count the number of users to create
109
- */
110
- function mockRoomMembers ( room : Room , count : number ) {
111
- const members = Array ( count )
112
- . fill ( 0 )
113
- . map ( ( _ , index ) => new RoomMember ( room . roomId , "@alice:example.org" ) ) ;
114
-
115
- room . currentState . setJoinedMemberCount ( members . length ) ;
116
- room . getJoinedMembers = jest . fn ( ) . mockReturnValue ( members ) ;
117
- }
0 commit comments