test(timeline): add a test for the mysterious missing timeline start case

This commit is contained in:
Benjamin Bouvier
2025-06-04 16:21:45 +02:00
committed by Ivan Enderlin
parent a855f1df2c
commit 766ff3f8e9
2 changed files with 83 additions and 18 deletions

View File

@@ -1191,21 +1191,18 @@ async fn test_from_an_empty_timeline_paginate_zero_event_and_then_sync_some_even
// Receive 3 events.
mock_server
.mock_sync()
.ok_and_run(&client, |sync_builder| {
sync_builder.add_joined_room({
let mut room = JoinedRoomBuilder::new(room_id);
.sync_room(&client, {
let mut room = JoinedRoomBuilder::new(room_id);
for nth in 0..3 {
room = room.add_timeline_event(
event_factory
.text_msg("foo")
.event_id(&EventId::parse(format!("$ev{nth}")).unwrap()),
);
}
for nth in 0..3 {
room = room.add_timeline_event(
event_factory
.text_msg("foo")
.event_id(&EventId::parse(format!("$ev{nth}")).unwrap()),
);
}
room
});
room
})
.await;
@@ -1230,3 +1227,68 @@ async fn test_from_an_empty_timeline_paginate_zero_event_and_then_sync_some_even
// Nothing more!
assert_pending!(timeline_stream);
}
#[async_test]
async fn test_timeline_start_properly_inserted_when_created() {
let room_id = room_id!("!foo:bar.baz");
let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;
client.event_cache().subscribe().unwrap();
let room = mock_server
.sync_room(
&client,
JoinedRoomBuilder::new(room_id).set_timeline_prev_batch("previous-batch"),
)
.await;
let timeline = room.timeline().await.unwrap();
let (initial_items, mut stream) = timeline.subscribe().await;
assert!(initial_items.is_empty());
assert_pending!(stream);
// Paginate to reach the timeline start.
{
let _network_pagination = mock_server
.mock_room_messages()
.match_from("previous-batch")
.ok(
// No previous batch token, the beginning of the timeline is reached.
// It returns zero event, we want an empty timeline.
RoomMessagesResponseTemplate::default(),
)
.mock_once()
.mount_as_scoped()
.await;
let hit_end_of_timeline = timeline.paginate_backwards(5).await.unwrap();
assert!(hit_end_of_timeline);
// The start of the timeline is inserted.
assert_timeline_stream! {
[stream]
prepend --- timeline start ---;
};
assert_pending!(stream);
}
// Create a new timeline while this one is alive (so that the room event cache
// doesn't unload the linked chunk), and make sure it contains the timeline
// start as soon as possible.
let timeline2 = room.timeline().await.unwrap();
let (items, mut stream2) = timeline2.subscribe().await;
assert!(items.is_empty());
timeline2.live_back_pagination_status().await;
assert_timeline_stream! {
[stream2]
prepend --- timeline start ---;
};
assert_pending!(stream2);
}

View File

@@ -338,11 +338,14 @@ macro_rules! assert_timeline_stream {
};
( [ $stream:ident ] $( $all:tt )* ) => {
let mut timeline_updates = $stream
.next()
.await
.expect("Failed to poll the stream")
.into_iter();
let mut timeline_updates = tokio::time::timeout(
std::time::Duration::from_secs(1),
$stream .next()
)
.await
.expect("Timeline stream never sent an update")
.expect("Failed to poll the stream")
.into_iter();
assert_timeline_stream!( @_ [ timeline_updates ] [ $( $all )* ] [] )
};