@@ -176,8 +176,21 @@ async fn test_skip_count_is_taken_into_account_in_pagination_status() {
176176 let server = MatrixMockServer :: new ( ) . await ;
177177 let client = server. client_builder ( ) . build ( ) . await ;
178178
179+ client. event_cache ( ) . subscribe ( ) . unwrap ( ) ;
180+
179181 let room_id = room_id ! ( "!a98sd12bjh:example.org" ) ;
180- let room = server. sync_joined_room ( & client, room_id) . await ;
182+
183+ // Provide the room with a previous-batch token, to speed up the first
184+ // pagination (so we don't have to wait for such a token from sync, when
185+ // paginating).
186+ let room = server
187+ . sync_room (
188+ & client,
189+ JoinedRoomBuilder :: new ( room_id)
190+ . set_timeline_limited ( )
191+ . set_timeline_prev_batch ( "previous-batch" ) ,
192+ )
193+ . await ;
181194
182195 server. mock_room_state_encryption ( ) . plain ( ) . mount ( ) . await ;
183196
@@ -199,9 +212,11 @@ async fn test_skip_count_is_taken_into_account_in_pagination_status() {
199212 // Return 30 events in this pagination.
200213 let mut events = Vec :: new ( ) ;
201214 for i in 0 ..30 {
215+ // Invert indices, so that in the event cache they end ordered from $0 to $29.
216+ let j = 29 - i;
202217 events. push (
203- f. text_msg ( format ! ( "hello world {i }" ) )
204- . event_id ( & EventId :: parse ( format ! ( "$ev{i }" ) ) . unwrap ( ) ) ,
218+ f. text_msg ( format ! ( "hello world {j }" ) )
219+ . event_id ( & EventId :: parse ( format ! ( "$ev{j }" ) ) . unwrap ( ) ) ,
205220 ) ;
206221 }
207222 events
@@ -213,45 +228,74 @@ async fn test_skip_count_is_taken_into_account_in_pagination_status() {
213228 let hit_start = timeline. paginate_backwards ( 30 ) . await . unwrap ( ) ;
214229 assert ! ( hit_start) ;
215230
231+ // We get updates for the events, and the timeline start.
232+ assert_let_timeout ! ( Some ( timeline_updates) = timeline_stream. next( ) ) ;
233+ assert_eq ! ( timeline_updates. len( ) , 39 ) ;
234+
235+ for i in 0 ..18 {
236+ // the item itself.
237+ assert_let ! ( VectorDiff :: PushBack { value: message } = & timeline_updates[ 2 * i] ) ;
238+ assert_let ! ( Some ( msg) = message. as_event( ) . unwrap( ) . content( ) . as_message( ) ) ;
239+ assert_let ! ( MessageType :: Text ( text) = msg. msgtype( ) ) ;
240+ assert ! ( text. body. starts_with( "hello world" ) ) ;
241+
242+ // update for the read receipt.
243+ assert_let ! (
244+ VectorDiff :: Set { index: updated_index, value: _ } = & timeline_updates[ 2 * i + 1 ]
245+ ) ;
246+ assert_eq ! ( * updated_index, i) ;
247+ }
248+
249+ // After the loop, the last index that's been peeked is 2*17+1 == 35.
250+ // These three happen differently, because we're getting closer to the initial
251+ // maximum skip count value.
216252 {
217- // Before the event cache returns the items, it will report that we've hit the
218- // timeline start.
219- assert_let_timeout ! ( Some ( timeline_updates) = timeline_stream. next( ) ) ;
220- assert_eq ! ( dbg!( & timeline_updates) . len( ) , 1 ) ;
221- assert_let ! ( VectorDiff :: PushFront { value: start } = & timeline_updates[ 0 ] ) ;
222- assert ! ( start. is_timeline_start( ) ) ;
253+ assert_let ! ( VectorDiff :: PushBack { value: message } = & timeline_updates[ 36 ] ) ;
254+ assert_let ! ( Some ( msg) = message. as_event( ) . unwrap( ) . content( ) . as_message( ) ) ;
255+ assert_let ! ( MessageType :: Text ( text) = msg. msgtype( ) ) ;
256+ assert ! ( text. body. starts_with( "hello world" ) ) ;
257+
258+ assert_let ! ( VectorDiff :: PushFront { value: message } = & timeline_updates[ 37 ] ) ;
259+ assert_let ! ( Some ( msg) = message. as_event( ) . unwrap( ) . content( ) . as_message( ) ) ;
260+ assert_let ! ( MessageType :: Text ( text) = msg. msgtype( ) ) ;
261+ assert ! ( text. body. starts_with( "hello world" ) ) ;
262+
263+ assert_let ! ( VectorDiff :: PushFront { value: message } = & timeline_updates[ 38 ] ) ;
264+ assert_let ! ( Some ( msg) = message. as_event( ) . unwrap( ) . content( ) . as_message( ) ) ;
265+ assert_let ! ( MessageType :: Text ( text) = msg. msgtype( ) ) ;
266+ assert ! ( text. body. starts_with( "hello world" ) ) ;
223267 }
224268
225- // Then we get the events from the event cache.
269+ assert_pending ! ( timeline_stream) ;
270+ assert_next_eq ! ( back_pagination_status, PaginationStatus :: Idle { hit_timeline_start: false } ) ;
271+
272+ // If we back-paginate again, we'd get all the previous items, by adjusting the
273+ // skip count, but not hitting network.
274+ timeline. paginate_backwards ( 30 ) . await . unwrap ( ) ;
275+
226276 assert_let_timeout ! ( Some ( timeline_updates) = timeline_stream. next( ) ) ;
227- assert_eq ! ( timeline_updates. len( ) , 60 ) ;
277+ assert_eq ! ( timeline_updates. len( ) , 11 ) ;
228278
229- for i in 0 ..30 {
230- // the item itself
231- assert_let ! ( VectorDiff :: PushBack { value: message } = & timeline_updates[ 2 * i] ) ;
279+ for i in 0 ..9 {
280+ assert_let ! ( VectorDiff :: PushFront { value: message } = & timeline_updates[ i] ) ;
232281 assert_let ! ( Some ( msg) = message. as_event( ) . unwrap( ) . content( ) . as_message( ) ) ;
233282 assert_let ! ( MessageType :: Text ( text) = msg. msgtype( ) ) ;
234283 assert ! ( text. body. starts_with( "hello world" ) ) ;
284+ }
235285
236- if i != 29 {
237- // update for the read receipt.
238- assert_let ! (
239- VectorDiff :: Set { index: updated_index, value: _ } = & timeline_updates[ 2 * i + 1 ]
240- ) ;
241- // off by one, because of the timeline start.
242- assert_eq ! ( * updated_index, i + 1 ) ;
243- } else {
244- // The date divider is finally inserted after the timeline start.
245- assert_let ! (
246- VectorDiff :: Insert { index: 1 , value: date_divider } = & timeline_updates[ 2 * i + 1 ]
247- ) ;
248- assert ! ( date_divider. is_date_divider( ) ) ;
249- }
286+ {
287+ // Then the date divider is pushed at the front,
288+ assert_let ! ( VectorDiff :: PushFront { value } = & timeline_updates[ 9 ] ) ;
289+ assert ! ( value. is_date_divider( ) ) ;
250290 }
251291
252- assert_pending ! ( timeline_stream) ;
292+ {
293+ // Then the timeline start is pushed at the front,
294+ assert_let ! ( VectorDiff :: PushFront { value } = & timeline_updates[ 10 ] ) ;
295+ assert ! ( value. is_timeline_start( ) ) ;
296+ }
253297
254- assert_next_eq ! ( back_pagination_status , PaginationStatus :: Idle { hit_timeline_start : true } ) ;
298+ assert_pending ! ( timeline_stream ) ;
255299
256300 // Another timeline is opened, with the first one still open.
257301 let timeline2 = room. timeline ( ) . await . unwrap ( ) ;
0 commit comments