test: Adjust tests according to previous patches.

This patch adjust tests since the Event Cache ignores events from the
Send Queue if the cache is empty. It mostly impacts the tests as this
scenario is pretty rare in real world use cases.
This commit is contained in:
Ivan Enderlin
2026-04-02 16:27:01 +02:00
parent d68879d0aa
commit 63b8fc8b47
7 changed files with 60 additions and 125 deletions
@@ -78,7 +78,7 @@ async fn test_echo() {
send_hdl.await.unwrap().unwrap();
assert_let_timeout!(Some(timeline_updates) = timeline_stream.next());
assert_eq!(timeline_updates.len(), 5);
assert_eq!(timeline_updates.len(), 1);
// The `EventSendState` has been updated.
assert_let!(VectorDiff::Set { index: 1, value: sent_confirmation } = &timeline_updates[0]);
@@ -86,22 +86,6 @@ async fn test_echo() {
assert_matches!(item.send_state(), Some(EventSendState::Sent { .. }));
assert_eq!(item.event_id(), Some(event_id));
// The local event is removed.
assert_matches!(&timeline_updates[1], VectorDiff::Remove { index: 1 });
// The new event is inserted in the Event Cache: it comes as a remote event.
assert_let!(VectorDiff::PushFront { value: remote_event } = &timeline_updates[2]);
let item = remote_event.as_event().unwrap();
assert_let!(Some(msg) = item.content().as_message());
assert_let!(MessageType::Text(text) = msg.msgtype());
assert_eq!(text.body, "Hello, World!");
assert_eq!(item.event_id(), Some(event_id));
// The date divider is adjusted.
assert_let!(VectorDiff::PushFront { value: date_divider } = &timeline_updates[3]);
assert!(date_divider.is_date_divider());
assert_matches!(&timeline_updates[4], VectorDiff::Remove { index: 2 });
assert_pending!(timeline_stream);
let another_event_id = event_id!("$ev1");
@@ -257,7 +257,7 @@ async fn test_edit_local_echo() {
timeline.room().send_queue().set_enabled(true);
assert_let_timeout!(Some(timeline_updates) = timeline_stream.next());
assert_eq!(timeline_updates.len(), 5);
assert_eq!(timeline_updates.len(), 1);
// Observe the event being sent, and replacing the local echo.
assert_let!(VectorDiff::Set { index: 1, value: item } = &timeline_updates[0]);
@@ -266,17 +266,6 @@ async fn test_edit_local_echo() {
let edit_message = item.content().as_message().unwrap();
assert_eq!(edit_message.body(), "hello, world");
// Since the event is sent, it's inserted in the Event Cache, which
// transforms it as a remote event.
assert_matches!(&timeline_updates[1], VectorDiff::Remove { index: 1 });
assert_let!(VectorDiff::PushFront { value: remote_event } = &timeline_updates[2]);
assert_eq!(remote_event.as_event().unwrap().event_id().unwrap(), "$1");
// The date divider is adjusted.
assert_let!(VectorDiff::PushFront { value: date_divider } = &timeline_updates[3]);
assert!(date_divider.is_date_divider());
assert_matches!(&timeline_updates[4], VectorDiff::Remove { index: 2 });
// No new updates.
assert_pending!(timeline_stream);
}
@@ -574,12 +574,6 @@ async fn test_send_media_with_thumbnail() -> TestResult {
.unwrap();
// And the thumbnail data still matches what we've sent.
assert_eq!(retrieved_thumbnail_data, thumbnail_data);
// Since it's sent, it's inserted in the Event Cache, and reinserted as a
// remote event.
assert_let_timeout!(Some(VectorDiff::Remove { index: 0 }) = timeline_stream.next());
assert_let_timeout!(Some(VectorDiff::PushFront { value: item }) = timeline_stream.next());
assert_eq!(item.event_id().unwrap(), event_id!("$media"));
}
// That's all, folks!
@@ -519,7 +519,7 @@ async fn test_redact_local_sent_message() {
assert!(date_divider.is_date_divider());
assert_let_timeout!(Some(timeline_updates) = timeline_stream.next());
assert_eq!(timeline_updates.len(), 5);
assert_eq!(timeline_updates.len(), 1);
// We receive an update in the timeline from the send queue.
assert_let!(VectorDiff::Set { index: 1, value: item } = &timeline_updates[0]);
@@ -527,17 +527,6 @@ async fn test_redact_local_sent_message() {
assert!(event.is_local_echo());
assert_matches!(event.send_state(), Some(EventSendState::Sent { .. }));
// And then it's inserted in the Event Cache, and considered remote.
assert_matches!(&timeline_updates[1], VectorDiff::Remove { index: 1 });
assert_let!(VectorDiff::PushFront { value: remote_event } = &timeline_updates[2]);
assert_eq!(remote_event.as_event().unwrap().event_id(), Some(event_id));
// The date divider is adjusted.
assert_let!(VectorDiff::PushFront { value: date_divider } = &timeline_updates[3]);
assert!(date_divider.is_date_divider());
assert_matches!(&timeline_updates[4], VectorDiff::Remove { index: 2 });
assert_pending!(timeline_stream);
// Mock the redaction response for the event we just sent. Ensure it's called
@@ -84,12 +84,6 @@ async fn test_message_order() {
assert_eq!(value.event_id().unwrap(), "$ev0");
});
// The sent event is added in the Event Cache and becomes a remote event.
assert_next_matches!(timeline_stream, VectorDiff::Remove { index: 0 });
assert_next_matches!(timeline_stream, VectorDiff::PushFront { value: remote_event } => {
assert_eq!(remote_event.event_id().unwrap(), "$ev0");
});
// Then the second one.
assert_next_matches!(timeline_stream, VectorDiff::Set { index: 1, value } => {
assert!(value.is_editable(), "remote echo of second can be edited");
@@ -97,12 +91,6 @@ async fn test_message_order() {
assert_eq!(value.event_id().unwrap(), "$ev1");
});
// The sent event is added in the Event Cache and becomes a remote event.
assert_next_matches!(timeline_stream, VectorDiff::Remove { index: 1 });
assert_next_matches!(timeline_stream, VectorDiff::PushBack { value: remote_event } => {
assert_eq!(remote_event.event_id().unwrap(), "$ev1");
});
assert_pending!(timeline_stream);
}
@@ -180,13 +168,6 @@ async fn test_retry_order() {
assert_eq!(value.event_id().unwrap(), "$ev0");
});
// Once sent, the message is added in the Event Cache, thus it becomes a remote
// event.
assert_next_matches!(timeline_stream, VectorDiff::Remove { index: 0 });
assert_next_matches!(timeline_stream, VectorDiff::PushFront { value: remote_event } => {
assert_eq!(remote_event.event_id(), Some(event_id!("$ev0")));
});
// Then the second.
assert_next_matches!(timeline_stream, VectorDiff::Set { index: 1, value } => {
assert_eq!(value.content().as_message().unwrap().body(), "Second.");
@@ -194,13 +175,6 @@ async fn test_retry_order() {
assert_eq!(value.event_id().unwrap(), "$ev1");
});
// Once sent, the message is added in the Event Cache, thus it becomes a remote
// event.
assert_next_matches!(timeline_stream, VectorDiff::Remove { index: 1 });
assert_next_matches!(timeline_stream, VectorDiff::PushBack { value: remote_event } => {
assert_eq!(remote_event.event_id(), Some(event_id!("$ev1")));
});
assert_pending!(timeline_stream);
}
@@ -400,7 +374,7 @@ async fn test_no_duplicate_date_divider() {
sleep(Duration::from_millis(500)).await;
assert_let_timeout!(Some(timeline_updates) = timeline_stream.next());
assert_eq!(timeline_updates.len(), 8);
assert_eq!(timeline_updates.len(), 2);
// The first item should be updated first.
assert_let!(VectorDiff::Set { index: 1, value } = &timeline_updates[0]);
@@ -411,23 +385,7 @@ async fn test_no_duplicate_date_divider() {
assert_eq!(value.content().as_message().unwrap().body(), "First!");
assert_eq!(value.event_id().unwrap(), "$ev0");
// Now they are sent, they are inserted in the Event Cache, and thus become
// remote events.
assert_matches!(&timeline_updates[1], VectorDiff::Remove { index: 1 });
assert_let!(VectorDiff::PushFront { value: remote_event } = &timeline_updates[2]);
assert_eq!(remote_event.as_event().unwrap().event_id().unwrap(), "$ev0");
// Now the date divider is adjusted.
assert_let!(VectorDiff::PushFront { value: date_divider } = &timeline_updates[3]);
assert!(date_divider.is_date_divider());
assert_matches!(&timeline_updates[4], VectorDiff::Remove { index: 2 });
assert_let!(VectorDiff::Set { index: 2, value: remote_event } = &timeline_updates[5]);
assert_eq!(remote_event.as_event().unwrap().event_id().unwrap(), "$ev1");
assert_matches!(&timeline_updates[6], VectorDiff::Remove { index: 2 });
assert_let!(VectorDiff::PushBack { value: remote_event } = &timeline_updates[7]);
assert_let!(VectorDiff::Set { index: 2, value: remote_event } = &timeline_updates[1]);
assert_eq!(remote_event.as_event().unwrap().event_id().unwrap(), "$ev1");
assert_pending!(timeline_stream);
@@ -456,13 +414,13 @@ async fn test_no_duplicate_date_divider() {
.await;
assert_let_timeout!(Some(timeline_updates) = timeline_stream.next());
assert_eq!(timeline_updates.len(), 2);
assert_eq!(timeline_updates.len(), 4);
assert_let!(VectorDiff::PushBack { value } = &timeline_updates[0]);
assert_let!(VectorDiff::PushFront { value } = &timeline_updates[0]);
let value = value.as_event().unwrap();
assert_eq!(value.event_id().unwrap(), "$ev2");
assert_let!(VectorDiff::PushBack { value } = &timeline_updates[1]);
assert_let!(VectorDiff::Insert { index: 1, value } = &timeline_updates[1]);
let value = value.as_event().unwrap();
assert_eq!(value.event_id().unwrap(), "$ev3");
@@ -388,7 +388,7 @@ async fn test_local_reaction_to_local_echo() {
// Now, wait for the remote echo for the message itself.
{
assert_let_timeout!(Duration::from_secs(2), Some(timeline_updates) = stream.next());
assert_eq!(timeline_updates.len(), 5);
assert_eq!(timeline_updates.len(), 1);
assert_let!(VectorDiff::Set { index: 1, value: item } = &timeline_updates[0]);
let item = item.as_event().unwrap();
@@ -403,17 +403,6 @@ async fn test_local_reaction_to_local_echo() {
// TODO: why not LocalToRemote here?
assert_matches!(&reaction_info.status, ReactionStatus::LocalToLocal(..));
// And since the local event has been sent, it is inserted in the Event
// Cache, which transforms it to a remote event.
assert_matches!(&timeline_updates[1], VectorDiff::Remove { index: 1 });
assert_let!(VectorDiff::PushFront { value: remote_event } = &timeline_updates[2]);
assert_eq!(remote_event.as_event().unwrap().event_id(), Some(event_id!("$0")));
// Adjust the date divider.
assert_let!(VectorDiff::PushFront { value: date_divider } = &timeline_updates[3]);
assert!(date_divider.is_date_divider());
assert_pending!(stream);
}
@@ -1914,13 +1914,23 @@ async fn test_reactions() {
#[async_test]
async fn test_redaction() {
let f = EventFactory::new();
let server = MatrixMockServer::new().await;
let client = server.client_builder().build().await;
client.event_cache().subscribe().unwrap();
let room_id = room_id!("!a:b.c");
let room = server.sync_joined_room(&client, room_id).await;
// Create a non-empty room, so that the Event Cache is not empty, and we can see
// the Send Queue injecting events in the Event Cache.
let room = server
.sync_room(
&client,
JoinedRoomBuilder::new(room_id).add_timeline_event(f.text_msg("coucou").sender(*ALICE)),
)
.await;
sleep(Duration::from_millis(500)).await;
server.mock_room_state_encryption().plain().mount().await;
@@ -1933,7 +1943,7 @@ async fn test_redaction() {
// ----------------------
// Sanity check: the cache and queue are empty at the start.
assert!(events.is_empty());
assert_eq!(events.len(), 1);
assert!(local_echoes.is_empty());
assert!(watch.is_empty());
@@ -1991,7 +2001,7 @@ async fn test_redaction() {
assert_eq!(values.len(), 1);
assert_eq!(values[0].event_id().as_deref().unwrap(), redaction_event_id);
// The target event is now redacted.
assert_let!(VectorDiff::Set { index: 0, value: redacted_event } = &up.diffs[1]);
assert_let!(VectorDiff::Set { index: 1, value: redacted_event } = &up.diffs[1]);
let ev = redacted_event.raw().deserialize().unwrap();
assert_let!(AnySyncTimelineEvent::MessageLike(AnySyncMessageLikeEvent::RoomMessage(ev)) = ev);
assert_matches!(ev.as_original(), None);
@@ -3981,22 +3991,45 @@ async fn test_sending_reply_in_thread_auto_subscribe() {
#[async_test]
async fn test_sending_event_still_saves_sync_gap() {
let server = MatrixMockServer::new().await;
let client = server.client_builder().build().await;
client.event_cache().subscribe().unwrap();
let room_id = room_id!("!a:b.c");
let own_user_id = client.user_id().unwrap();
let f = EventFactory::new().room(room_id).sender(own_user_id);
let room = server.sync_joined_room(&client, room_id).await;
server.mock_room_state_encryption().plain().mount().await;
// The room receives one event from the sync.
// This is mandatory, otherwise the event will not be inserted in the Event
// Cache by the Send Queue (because the Event Cache is empty, see the
// documentation of
// `RoomEventCacheInner::test_sending_event_still_saves_sync_gap`).
server
.mock_sync()
.ok_and_run(&client, |builder| {
builder.add_joined_room(
JoinedRoomBuilder::new(room_id)
.add_timeline_event(f.text_msg("first!").event_id(event_id!("$first")))
.set_timeline_prev_batch("first_batch")
.set_timeline_limited(),
);
})
.await;
// Give time to the Event Cache to handle the sync.
sleep(Duration::from_secs(1)).await;
let (room_event_cache, _drop_handles) = room.event_cache().await.unwrap();
let (events, mut stream) = room_event_cache.subscribe().await.unwrap();
// Sanity check: there's no event in the room at start.
assert!(events.is_empty());
assert_eq!(events.len(), 1);
// Send a message in the room.
let content = RoomMessageEventContent::text_plain("hello world");
@@ -4013,20 +4046,17 @@ async fn test_sending_event_still_saves_sync_gap() {
assert_eq!(values[0].event_id().as_deref().unwrap(), event_id!("$msg_now"));
// Now, assume that a /sync response comes with only this message as part of the
// response, and with a previous gap. This can happen under real-world
// conditions, like the timeline_limit being set to 1, and a fast client
// sending an event before the timeline_limit is updated to another value.
let own_user_id = client.user_id().unwrap();
let f = EventFactory::new().room(room_id).sender(own_user_id);
// response, and with a previous gap.
server
.sync_room(
&client,
JoinedRoomBuilder::new(room_id)
.add_timeline_event(f.text_msg("hello world").event_id(event_id!("$msg_now")))
.set_timeline_prev_batch("prev_batch")
.set_timeline_limited(),
)
.mock_sync()
.ok_and_run(&client, |builder| {
builder.add_joined_room(
JoinedRoomBuilder::new(room_id)
.add_timeline_event(f.text_msg("hello world").event_id(event_id!("$msg_now")))
.set_timeline_prev_batch("prev_batch")
.set_timeline_limited(),
);
})
.await;
// After syncing, since a gap was saved, the cache should unload the chunk and
@@ -4050,11 +4080,13 @@ async fn test_sending_event_still_saves_sync_gap() {
// Run a pagination; it should return the past message.
let outcome = room_event_cache.pagination().run_backwards_once(42).await.unwrap();
assert!(outcome.reached_start);
assert!(outcome.reached_start.not());
// We should have received the past message.
assert_let_timeout!(Ok(RoomEventCacheUpdate::UpdateTimelineEvents(update)) = stream.recv());
assert_eq!(update.diffs.len(), 1);
assert_let!(VectorDiff::Insert { index: 0, value: event } = &update.diffs[0]);
assert_eq!(event.event_id().as_deref().unwrap(), event_id!("$past_msg"));
assert!(stream.is_empty());
}