16
16
17
17
use std:: time:: Duration ;
18
18
19
- use assert_matches:: assert_matches;
20
19
use assert_matches2:: assert_let;
21
20
use eyeball_im:: VectorDiff ;
22
21
use futures_util:: StreamExt ;
@@ -25,33 +24,29 @@ use matrix_sdk::{
25
24
test_utils:: { events:: EventFactory , logged_in_client_with_server} ,
26
25
} ;
27
26
use matrix_sdk_test:: {
28
- async_test, sync_timeline_event, JoinedRoomBuilder , RoomAccountDataTestEvent , StateTestEvent ,
29
- SyncResponseBuilder , ALICE , BOB ,
27
+ async_test, sync_timeline_event, JoinedRoomBuilder , SyncResponseBuilder , ALICE , BOB ,
30
28
} ;
31
- use matrix_sdk_ui:: {
32
- timeline:: { RoomExt , TimelineFocus , TimelineItemContent , VirtualTimelineItem } ,
33
- Timeline ,
34
- } ;
35
- use ruma:: { event_id, room_id, user_id} ;
29
+ use matrix_sdk_ui:: { timeline:: TimelineFocus , Timeline } ;
30
+ use ruma:: { event_id, room_id} ;
36
31
use stream_assert:: assert_pending;
37
32
38
- use crate :: { mock_context, mock_sync} ;
33
+ use crate :: { mock_context, mock_messages , mock_sync} ;
39
34
40
35
#[ async_test]
41
36
async fn test_new_focused ( ) {
42
37
let room_id = room_id ! ( "!a98sd12bjh:example.org" ) ;
43
38
let ( client, server) = logged_in_client_with_server ( ) . await ;
44
39
let sync_settings = SyncSettings :: new ( ) . timeout ( Duration :: from_millis ( 3000 ) ) ;
45
40
46
- let mut ev_builder = SyncResponseBuilder :: new ( ) ;
47
- ev_builder . add_joined_room ( JoinedRoomBuilder :: new ( room_id) ) ;
41
+ let mut sync_response_builder = SyncResponseBuilder :: new ( ) ;
42
+ sync_response_builder . add_joined_room ( JoinedRoomBuilder :: new ( room_id) ) ;
48
43
49
44
// Mark the room as joined.
50
- mock_sync ( & server, ev_builder . build_json_sync_response ( ) , None ) . await ;
45
+ mock_sync ( & server, sync_response_builder . build_json_sync_response ( ) , None ) . await ;
51
46
let _response = client. sync_once ( sync_settings. clone ( ) ) . await . unwrap ( ) ;
52
47
server. reset ( ) . await ;
53
48
54
- let factory = EventFactory :: new ( ) . room ( room_id) ;
49
+ let f = EventFactory :: new ( ) . room ( room_id) ;
55
50
let target_event = event_id ! ( "$1" ) ;
56
51
57
52
mock_context (
@@ -60,13 +55,13 @@ async fn test_new_focused() {
60
55
target_event,
61
56
Some ( "prev1" . to_owned ( ) ) ,
62
57
vec ! [
63
- factory . text_msg( "i tried so hard" ) . sender( * ALICE ) . into_timeline( ) ,
64
- factory . text_msg( "and got so far" ) . sender( * ALICE ) . into_timeline( ) ,
58
+ f . text_msg( "i tried so hard" ) . sender( * ALICE ) . into_timeline( ) ,
59
+ f . text_msg( "and got so far" ) . sender( * ALICE ) . into_timeline( ) ,
65
60
] ,
66
- factory . text_msg ( "in the end" ) . sender ( * BOB ) . into_timeline ( ) ,
61
+ f . text_msg ( "in the end" ) . event_id ( target_event ) . sender ( * BOB ) . into_timeline ( ) ,
67
62
vec ! [
68
- factory . text_msg( "it doesn't even" ) . sender( * ALICE ) . into_timeline( ) ,
69
- factory . text_msg( "matter" ) . sender( * ALICE ) . into_timeline( ) ,
63
+ f . text_msg( "it doesn't even" ) . sender( * ALICE ) . into_timeline( ) ,
64
+ f . text_msg( "matter" ) . sender( * ALICE ) . into_timeline( ) ,
70
65
] ,
71
66
Some ( "next1" . to_owned ( ) ) ,
72
67
vec ! [ ] ,
@@ -105,4 +100,168 @@ async fn test_new_focused() {
105
100
assert_eq ! ( items[ 5 ] . as_event( ) . unwrap( ) . content( ) . as_message( ) . unwrap( ) . body( ) , "matter" ) ;
106
101
107
102
assert_pending ! ( timeline_stream) ;
103
+
104
+ // Now trigger a backward pagination.
105
+ mock_messages (
106
+ & server,
107
+ "prev1" . to_owned ( ) ,
108
+ None ,
109
+ vec ! [
110
+ // reversed manually here
111
+ f. text_msg( "And even though I tried, it all fell apart" ) . sender( * BOB ) . into_timeline( ) ,
112
+ f. text_msg( "I kept everything inside" ) . sender( * BOB ) . into_timeline( ) ,
113
+ ] ,
114
+ vec ! [ ] ,
115
+ )
116
+ . await ;
117
+
118
+ let hit_start = timeline. focused_paginate_backwards ( 20 ) . await . unwrap ( ) ;
119
+ assert ! ( hit_start) ;
120
+
121
+ server. reset ( ) . await ;
122
+
123
+ assert_let ! ( Some ( VectorDiff :: PushFront { value: message } ) = timeline_stream. next( ) . await ) ;
124
+ assert_eq ! (
125
+ message. as_event( ) . unwrap( ) . content( ) . as_message( ) . unwrap( ) . body( ) ,
126
+ "And even though I tried, it all fell apart"
127
+ ) ;
128
+
129
+ assert_let ! ( Some ( VectorDiff :: PushFront { value: message } ) = timeline_stream. next( ) . await ) ;
130
+ assert_eq ! (
131
+ message. as_event( ) . unwrap( ) . content( ) . as_message( ) . unwrap( ) . body( ) ,
132
+ "I kept everything inside"
133
+ ) ;
134
+
135
+ // Day divider post processing.
136
+ assert_let ! ( Some ( VectorDiff :: PushFront { value: item } ) = timeline_stream. next( ) . await ) ;
137
+ assert ! ( item. is_day_divider( ) ) ;
138
+ assert_let ! ( Some ( VectorDiff :: Remove { index } ) = timeline_stream. next( ) . await ) ;
139
+ assert_eq ! ( index, 3 ) ;
140
+
141
+ // Now trigger a forward pagination.
142
+ mock_messages (
143
+ & server,
144
+ "next1" . to_owned ( ) ,
145
+ Some ( "next2" . to_owned ( ) ) ,
146
+ vec ! [
147
+ f. text_msg( "I had to fall, to lose it all" ) . sender( * BOB ) . into_timeline( ) ,
148
+ f. text_msg( "But in the end, it doesn't event matter" ) . sender( * BOB ) . into_timeline( ) ,
149
+ ] ,
150
+ vec ! [ ] ,
151
+ )
152
+ . await ;
153
+
154
+ let hit_start = timeline. focused_paginate_forwards ( 20 ) . await . unwrap ( ) ;
155
+ assert ! ( !hit_start) ; // because we gave it another next2 token.
156
+
157
+ server. reset ( ) . await ;
158
+
159
+ assert_let ! ( Some ( VectorDiff :: PushBack { value: message } ) = timeline_stream. next( ) . await ) ;
160
+ assert_eq ! (
161
+ message. as_event( ) . unwrap( ) . content( ) . as_message( ) . unwrap( ) . body( ) ,
162
+ "I had to fall, to lose it all"
163
+ ) ;
164
+
165
+ assert_let ! ( Some ( VectorDiff :: PushBack { value: message } ) = timeline_stream. next( ) . await ) ;
166
+ assert_eq ! (
167
+ message. as_event( ) . unwrap( ) . content( ) . as_message( ) . unwrap( ) . body( ) ,
168
+ "But in the end, it doesn't event matter"
169
+ ) ;
170
+
171
+ assert_pending ! ( timeline_stream) ;
172
+ }
173
+
174
+ #[ async_test]
175
+ async fn test_focused_timeline_reacts ( ) {
176
+ let room_id = room_id ! ( "!a98sd12bjh:example.org" ) ;
177
+ let ( client, server) = logged_in_client_with_server ( ) . await ;
178
+ let sync_settings = SyncSettings :: new ( ) . timeout ( Duration :: from_millis ( 3000 ) ) ;
179
+
180
+ let mut sync_response_builder = SyncResponseBuilder :: new ( ) ;
181
+ sync_response_builder. add_joined_room ( JoinedRoomBuilder :: new ( room_id) ) ;
182
+
183
+ // Mark the room as joined.
184
+ mock_sync ( & server, sync_response_builder. build_json_sync_response ( ) , None ) . await ;
185
+ let _response = client. sync_once ( sync_settings. clone ( ) ) . await . unwrap ( ) ;
186
+ server. reset ( ) . await ;
187
+
188
+ // Start a focused timeline.
189
+ let f = EventFactory :: new ( ) . room ( room_id) ;
190
+ let target_event = event_id ! ( "$1" ) ;
191
+
192
+ mock_context (
193
+ & server,
194
+ room_id,
195
+ target_event,
196
+ None ,
197
+ vec ! [ ] ,
198
+ f. text_msg ( "yolo" ) . event_id ( target_event) . sender ( * BOB ) . into_timeline ( ) ,
199
+ vec ! [ ] ,
200
+ None ,
201
+ vec ! [ ] ,
202
+ )
203
+ . await ;
204
+
205
+ let room = client. get_room ( room_id) . unwrap ( ) ;
206
+ let timeline = Timeline :: builder ( & room)
207
+ . with_focus ( TimelineFocus :: Event {
208
+ target : target_event. to_owned ( ) ,
209
+ num_context_events : 20 ,
210
+ } )
211
+ . build ( )
212
+ . await
213
+ . unwrap ( ) ;
214
+
215
+ server. reset ( ) . await ;
216
+
217
+ let ( items, mut timeline_stream) = timeline. subscribe ( ) . await ;
218
+
219
+ assert_eq ! ( items. len( ) , 1 + 1 ) ; // event items + a day divider
220
+ assert ! ( items[ 0 ] . is_day_divider( ) ) ;
221
+
222
+ let event_item = items[ 1 ] . as_event ( ) . unwrap ( ) ;
223
+ assert_eq ! ( event_item. content( ) . as_message( ) . unwrap( ) . body( ) , "yolo" ) ;
224
+ assert_eq ! ( event_item. reactions( ) . len( ) , 0 ) ;
225
+
226
+ assert_pending ! ( timeline_stream) ;
227
+
228
+ // Now simulate a sync that returns a new message-like event, and a reaction
229
+ // to the $1 event.
230
+ sync_response_builder. add_joined_room ( JoinedRoomBuilder :: new ( room_id) . add_timeline_bulk ( [
231
+ // This event must be ignored.
232
+ f. text_msg ( "this is a sync event" ) . sender ( * ALICE ) . into_raw_sync ( ) ,
233
+ // This event must not be ignored.
234
+ sync_timeline_event ! ( {
235
+ "content" : {
236
+ "m.relates_to" : {
237
+ "event_id" : "$1" ,
238
+ "key" : "👍" ,
239
+ "rel_type" : "m.annotation"
240
+ }
241
+ } ,
242
+ "event_id" : "$15275047031IXQRi:localhost" ,
243
+ "origin_server_ts" : 159027581000000_u64 ,
244
+ "sender" : * BOB ,
245
+ "type" : "m.reaction" ,
246
+ "unsigned" : {
247
+ "age" : 85
248
+ }
249
+ } ) ,
250
+ ] ) ) ;
251
+
252
+ // Sync the room.
253
+ mock_sync ( & server, sync_response_builder. build_json_sync_response ( ) , None ) . await ;
254
+ let _response = client. sync_once ( sync_settings. clone ( ) ) . await . unwrap ( ) ;
255
+ server. reset ( ) . await ;
256
+
257
+ assert_let ! ( Some ( VectorDiff :: Set { index: 1 , value: item } ) = timeline_stream. next( ) . await ) ;
258
+
259
+ let event_item = item. as_event ( ) . unwrap ( ) ;
260
+ // Text hasn't changed.
261
+ assert_eq ! ( event_item. content( ) . as_message( ) . unwrap( ) . body( ) , "yolo" ) ;
262
+ // But now there's one reaction to the event.
263
+ assert_eq ! ( event_item. reactions( ) . len( ) , 1 ) ;
264
+
265
+ // And nothing more.
266
+ assert_pending ! ( timeline_stream) ;
108
267
}
0 commit comments