diff --git a/bindings/matrix-sdk-ffi/src/client_builder.rs b/bindings/matrix-sdk-ffi/src/client_builder.rs index 2509758eb9f..e24884383ed 100644 --- a/bindings/matrix-sdk-ffi/src/client_builder.rs +++ b/bindings/matrix-sdk-ffi/src/client_builder.rs @@ -272,10 +272,6 @@ pub struct ClientBuilder { room_key_recipient_strategy: CollectStrategy, decryption_trust_requirement: TrustRequirement, request_config: Option, - - /// Whether to enable use of the event cache store, for reloading events - /// when building timelines et al. - use_event_cache_persistent_storage: bool, } #[matrix_sdk_ffi_macros::export] @@ -306,27 +302,9 @@ impl ClientBuilder { room_key_recipient_strategy: Default::default(), decryption_trust_requirement: TrustRequirement::Untrusted, request_config: Default::default(), - use_event_cache_persistent_storage: false, }) } - /// Whether to use the event cache persistent storage or not. - /// - /// This is a temporary feature flag, for testing the event cache's - /// persistent storage. Follow new developments in https://github.com/matrix-org/matrix-rust-sdk/issues/3280. - /// - /// This is disabled by default. When disabled, a one-time cleanup is - /// performed when creating the client, and it will clear all the events - /// previously stored in the event cache. - /// - /// When enabled, it will attempt to store events in the event cache as - /// they're received, and reuse them when reconstructing timelines. - pub fn use_event_cache_persistent_storage(self: Arc, value: bool) -> Arc { - let mut builder = unwrap_or_clone_arc(self); - builder.use_event_cache_persistent_storage = value; - Arc::new(builder) - } - pub fn cross_process_store_locks_holder_name( self: Arc, holder_name: String, @@ -649,19 +627,6 @@ impl ClientBuilder { let sdk_client = inner_builder.build().await?; - if builder.use_event_cache_persistent_storage { - // Enable the persistent storage \o/ - sdk_client.event_cache().enable_storage()?; - } else { - // Get rid of all the previous events, if any. - let store = sdk_client - .event_cache_store() - .lock() - .await - .map_err(EventCacheError::LockingStorage)?; - store.clear_all_rooms_chunks().await.map_err(EventCacheError::Storage)?; - } - Ok(Arc::new( Client::new(sdk_client, builder.enable_oidc_refresh_lock, builder.session_delegate) .await?, diff --git a/bindings/matrix-sdk-ffi/src/room_list.rs b/bindings/matrix-sdk-ffi/src/room_list.rs index 09e49da741d..7abfea0f0de 100644 --- a/bindings/matrix-sdk-ffi/src/room_list.rs +++ b/bindings/matrix-sdk-ffi/src/room_list.rs @@ -685,7 +685,6 @@ impl RoomListItem { let mut timeline_builder = self .inner .default_room_timeline_builder() - .await .map_err(|err| RoomListError::InitializingTimeline { error: err.to_string() })?; if let Some(event_type_filter) = event_type_filter { diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/all.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/all.rs index bf0fefd6c0e..0d8f617694d 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/all.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/all.rs @@ -24,18 +24,16 @@ pub fn new_filter(filters: Vec) -> impl Filter { mod tests { use std::ops::Not; + use matrix_sdk::test_utils::logged_in_client_with_server; use matrix_sdk_test::async_test; use ruma::room_id; - use super::{ - super::{client_and_server_prelude, new_rooms}, - *, - }; + use super::{super::new_rooms, *}; #[async_test] async fn test_one_filter() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; { let filter = |_: &_| true; @@ -54,8 +52,8 @@ mod tests { #[async_test] async fn test_two_filters() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; { let filter1 = |_: &_| true; diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/any.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/any.rs index 185b5a98252..86b0ecaf6a4 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/any.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/any.rs @@ -24,18 +24,16 @@ pub fn new_filter(filters: Vec) -> impl Filter { mod tests { use std::ops::Not; + use matrix_sdk::test_utils::logged_in_client_with_server; use matrix_sdk_test::async_test; use ruma::room_id; - use super::{ - super::{client_and_server_prelude, new_rooms}, - *, - }; + use super::{super::new_rooms, *}; #[async_test] async fn test_one_filter_is_true() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let filter = |_: &_| true; let any = new_filter(vec![Box::new(filter)]); @@ -45,8 +43,8 @@ mod tests { #[async_test] async fn test_one_filter_is_false() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let filter = |_: &_| false; let any = new_filter(vec![Box::new(filter)]); @@ -56,8 +54,8 @@ mod tests { #[async_test] async fn test_two_filters_with_true_true() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let filter1 = |_: &_| true; let filter2 = |_: &_| true; @@ -68,8 +66,8 @@ mod tests { #[async_test] async fn test_two_filters_with_true_false() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let filter1 = |_: &_| true; let filter2 = |_: &_| false; @@ -80,8 +78,8 @@ mod tests { #[async_test] async fn test_two_filters_with_false_true() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let filter1 = |_: &_| false; let filter2 = |_: &_| true; @@ -92,8 +90,8 @@ mod tests { #[async_test] async fn test_two_filters_with_false_false() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let filter1 = |_: &_| false; let filter2 = |_: &_| false; diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/category.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/category.rs index 288d0bc566a..79372720508 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/category.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/category.rs @@ -79,18 +79,16 @@ pub fn new_filter(expected_category: RoomCategory) -> impl Filter { mod tests { use std::ops::Not; + use matrix_sdk::test_utils::logged_in_client_with_server; use matrix_sdk_test::async_test; use ruma::room_id; - use super::{ - super::{client_and_server_prelude, new_rooms}, - *, - }; + use super::{super::new_rooms, *}; #[async_test] async fn test_kind_is_group() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let matcher = CategoryRoomMatcher { number_of_direct_targets: |_| Some(42) }; @@ -111,8 +109,8 @@ mod tests { #[async_test] async fn test_kind_is_people() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let matcher = CategoryRoomMatcher { number_of_direct_targets: |_| Some(1) }; @@ -133,8 +131,8 @@ mod tests { #[async_test] async fn test_room_kind_cannot_be_found() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let matcher = CategoryRoomMatcher { number_of_direct_targets: |_| None }; diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/favourite.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/favourite.rs index 6e187384351..279a939bf1e 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/favourite.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/favourite.rs @@ -42,18 +42,16 @@ pub fn new_filter() -> impl Filter { mod tests { use std::ops::Not; + use matrix_sdk::test_utils::logged_in_client_with_server; use matrix_sdk_test::async_test; use ruma::room_id; - use super::{ - super::{client_and_server_prelude, new_rooms}, - *, - }; + use super::{super::new_rooms, *}; #[async_test] async fn test_is_favourite() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let matcher = FavouriteRoomMatcher { is_favourite: |_| true }; @@ -62,8 +60,8 @@ mod tests { #[async_test] async fn test_is_not_favourite() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let matcher = FavouriteRoomMatcher { is_favourite: |_| false }; diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/invite.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/invite.rs index 8041c342c7c..c8879f09f28 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/invite.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/invite.rs @@ -42,19 +42,17 @@ pub fn new_filter() -> impl Filter { #[cfg(test)] mod tests { + use matrix_sdk::test_utils::logged_in_client_with_server; use matrix_sdk_base::RoomState; use matrix_sdk_test::async_test; use ruma::room_id; - use super::{ - super::{client_and_server_prelude, new_rooms}, - *, - }; + use super::{super::new_rooms, *}; #[async_test] async fn test_all_invite_kind() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; // When a room has been left, it doesn't match. let matcher = InviteRoomMatcher { state: |_| RoomState::Left }; diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/joined.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/joined.rs index ee1c6277881..b5ca056aa8e 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/joined.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/joined.rs @@ -42,19 +42,17 @@ pub fn new_filter() -> impl Filter { #[cfg(test)] mod tests { + use matrix_sdk::test_utils::logged_in_client_with_server; use matrix_sdk_base::RoomState; use matrix_sdk_test::async_test; use ruma::room_id; - use super::{ - super::{client_and_server_prelude, new_rooms}, - *, - }; + use super::{super::new_rooms, *}; #[async_test] async fn test_all_joined_kind() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; // When a room has been left, it doesn't match. let matcher = JoinedRoomMatcher { state: |_| RoomState::Left }; diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/mod.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/mod.rs index 2eb01063da0..881dbd6fad5 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/mod.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/mod.rs @@ -64,9 +64,6 @@ mod normalized_match_room_name; mod not; mod unread; -#[cfg(test)] -use std::sync::Arc; - pub use all::new_filter as new_filter_all; pub use any::new_filter as new_filter_any; pub use category::{new_filter as new_filter_category, RoomCategory}; @@ -75,7 +72,7 @@ pub use fuzzy_match_room_name::new_filter as new_filter_fuzzy_match_room_name; pub use invite::new_filter as new_filter_invite; pub use joined::new_filter as new_filter_joined; #[cfg(test)] -use matrix_sdk::{test_utils::logged_in_client_with_server, Client, SlidingSync}; +use matrix_sdk::Client; #[cfg(test)] use matrix_sdk_test::{JoinedRoomBuilder, SyncResponseBuilder}; pub use non_left::new_filter as new_filter_non_left; @@ -116,7 +113,6 @@ pub(super) async fn new_rooms( room_ids: [&RoomId; N], client: &Client, server: &MockServer, - sliding_sync: &Arc, ) -> [Room; N] { let mut response_builder = SyncResponseBuilder::default(); @@ -135,15 +131,7 @@ pub(super) async fn new_rooms( let _response = client.sync_once(Default::default()).await.unwrap(); - room_ids.map(|room_id| Room::new(client.get_room(room_id).unwrap(), sliding_sync)) -} - -#[cfg(test)] -pub(super) async fn client_and_server_prelude() -> (Client, MockServer, Arc) { - let (client, server) = logged_in_client_with_server().await; - let sliding_sync = Arc::new(client.sliding_sync("foo").unwrap().build().await.unwrap()); - - (client, server, sliding_sync) + room_ids.map(|room_id| Room::new(client.get_room(room_id).unwrap())) } #[cfg(test)] diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/non_left.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/non_left.rs index 05ceccd361c..d9b1a1bbedd 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/non_left.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/non_left.rs @@ -44,19 +44,17 @@ pub fn new_filter() -> impl Filter { #[cfg(test)] mod tests { + use matrix_sdk::test_utils::logged_in_client_with_server; use matrix_sdk_base::RoomState; use matrix_sdk_test::async_test; use ruma::room_id; - use super::{ - super::{client_and_server_prelude, new_rooms}, - *, - }; + use super::{super::new_rooms, *}; #[async_test] async fn test_all_non_left_kind_of_room_list_entry() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; // When a room has been left, it doesn't match. let matcher = NonLeftRoomMatcher { state: |_| RoomState::Left }; diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/none.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/none.rs index 3fe9f8aaabf..e409462f978 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/none.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/none.rs @@ -23,18 +23,16 @@ pub fn new_filter() -> impl Filter { mod tests { use std::ops::Not; + use matrix_sdk::test_utils::logged_in_client_with_server; use matrix_sdk_test::async_test; use ruma::room_id; - use super::{ - super::{client_and_server_prelude, new_rooms}, - *, - }; + use super::{super::new_rooms, *}; #[async_test] async fn test_all_kind_of_room_list_entry() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let none = new_filter(); diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/not.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/not.rs index c3b521ad692..9d70c125499 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/not.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/not.rs @@ -26,18 +26,16 @@ pub fn new_filter(filter: BoxedFilterFn) -> impl Filter { mod tests { use std::ops::Not; + use matrix_sdk::test_utils::logged_in_client_with_server; use matrix_sdk_test::async_test; use ruma::room_id; - use super::{ - super::{client_and_server_prelude, new_rooms}, - *, - }; + use super::{super::new_rooms, *}; #[async_test] async fn test_true() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let filter = Box::new(|_: &_| true); let not = new_filter(filter); @@ -47,8 +45,8 @@ mod tests { #[async_test] async fn test_false() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let filter = Box::new(|_: &_| false); let not = new_filter(filter); diff --git a/crates/matrix-sdk-ui/src/room_list_service/filters/unread.rs b/crates/matrix-sdk-ui/src/room_list_service/filters/unread.rs index a031c55a24a..0d7885af319 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/filters/unread.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/filters/unread.rs @@ -50,19 +50,17 @@ pub fn new_filter() -> impl Filter { mod tests { use std::ops::Not; + use matrix_sdk::test_utils::logged_in_client_with_server; use matrix_sdk_base::read_receipts::RoomReadReceipts; use matrix_sdk_test::async_test; use ruma::room_id; - use super::{ - super::{client_and_server_prelude, new_rooms}, - *, - }; + use super::{super::new_rooms, *}; #[async_test] async fn test_has_unread_notifications() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; for is_marked_as_unread in [true, false] { let matcher = UnreadRoomMatcher { @@ -81,8 +79,8 @@ mod tests { #[async_test] async fn test_has_unread_messages_but_no_unread_notifications_and_is_not_marked_as_unread() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let matcher = UnreadRoomMatcher { read_receipts_and_unread: |_| { @@ -99,8 +97,8 @@ mod tests { #[async_test] async fn test_has_unread_messages_but_no_unread_notifications_and_is_marked_as_unread() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let matcher = UnreadRoomMatcher { read_receipts_and_unread: |_| { @@ -117,8 +115,8 @@ mod tests { #[async_test] async fn test_has_no_unread_notifications_and_is_not_marked_as_unread() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let matcher = UnreadRoomMatcher { read_receipts_and_unread: |_| (RoomReadReceipts::default(), false), @@ -129,8 +127,8 @@ mod tests { #[async_test] async fn test_has_no_unread_notifications_and_is_marked_as_unread() { - let (client, server, sliding_sync) = client_and_server_prelude().await; - let [room] = new_rooms([room_id!("!a:b.c")], &client, &server, &sliding_sync).await; + let (client, server) = logged_in_client_with_server().await; + let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await; let matcher = UnreadRoomMatcher { read_receipts_and_unread: |_| (RoomReadReceipts::default(), true) }; diff --git a/crates/matrix-sdk-ui/src/room_list_service/mod.rs b/crates/matrix-sdk-ui/src/room_list_service/mod.rs index 37a36145c66..abeddda7f9b 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/mod.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/mod.rs @@ -378,7 +378,6 @@ impl RoomListService { pub fn room(&self, room_id: &RoomId) -> Result { Ok(Room::new( self.client.get_room(room_id).ok_or_else(|| Error::RoomNotFound(room_id.to_owned()))?, - &self.sliding_sync, )) } diff --git a/crates/matrix-sdk-ui/src/room_list_service/room.rs b/crates/matrix-sdk-ui/src/room_list_service/room.rs index ee444a20a91..504f27684a6 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/room.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/room.rs @@ -18,9 +18,7 @@ use core::fmt; use std::{ops::Deref, sync::Arc}; use async_once_cell::OnceCell as AsyncOnceCell; -use matrix_sdk::SlidingSync; use ruma::RoomId; -use tracing::info; use super::Error; use crate::{ @@ -43,9 +41,6 @@ impl fmt::Debug for Room { } struct RoomInner { - /// The Sliding Sync where everything comes from. - sliding_sync: Arc, - /// The underlying client room. room: matrix_sdk::Room, @@ -63,14 +58,8 @@ impl Deref for Room { impl Room { /// Create a new `Room`. - pub(super) fn new(room: matrix_sdk::Room, sliding_sync: &Arc) -> Self { - Self { - inner: Arc::new(RoomInner { - sliding_sync: sliding_sync.clone(), - room, - timeline: AsyncOnceCell::new(), - }), - } + pub(super) fn new(room: matrix_sdk::Room) -> Self { + Self { inner: Arc::new(RoomInner { room, timeline: AsyncOnceCell::new() }) } } /// Get the room ID. @@ -154,30 +143,7 @@ impl Room { /// /// If the room was synced before some initial events will be added to the /// [`TimelineBuilder`]. - pub async fn default_room_timeline_builder(&self) -> Result { - // TODO we can remove this once the event cache handles his own cache. - - let sliding_sync_room = self.inner.sliding_sync.get_room(self.inner.room.room_id()).await; - - if let Some(sliding_sync_room) = sliding_sync_room { - self.inner - .room - .client() - .event_cache() - .add_initial_events( - self.inner.room.room_id(), - sliding_sync_room.timeline_queue().iter().cloned().collect(), - sliding_sync_room.prev_batch(), - ) - .await - .map_err(Error::EventCache)?; - } else { - info!( - "No cached sliding sync room found for `{}`, the timeline will be empty.", - self.room_id() - ); - } - + pub fn default_room_timeline_builder(&self) -> Result { Ok(Timeline::builder(&self.inner.room).track_read_marker_and_receipts()) } } diff --git a/crates/matrix-sdk-ui/src/room_list_service/room_list.rs b/crates/matrix-sdk-ui/src/room_list_service/room_list.rs index 99d8fa10bb0..672c86da651 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/room_list.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/room_list.rs @@ -43,7 +43,6 @@ use super::{ #[derive(Debug)] pub struct RoomList { client: Client, - sliding_sync: Arc, sliding_sync_list: SlidingSyncList, loading_state: SharedObservable, loading_state_task: JoinHandle<()>, @@ -77,7 +76,6 @@ impl RoomList { Ok(Self { client: client.clone(), - sliding_sync: sliding_sync.clone(), sliding_sync_list: sliding_sync_list.clone(), loading_state: loading_state.clone(), loading_state_task: spawn(async move { @@ -124,7 +122,7 @@ impl RoomList { fn entries(&self) -> (Vector, impl Stream>> + '_) { let (rooms, stream) = self.client.rooms_stream(); - let map_room = |room| Room::new(room, &self.sliding_sync); + let map_room = |room| Room::new(room); ( rooms.into_iter().map(map_room).collect(), diff --git a/crates/matrix-sdk-ui/src/room_list_service/sorters/lexicographic.rs b/crates/matrix-sdk-ui/src/room_list_service/sorters/lexicographic.rs index 5b3048ef794..74e260c2aa9 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/sorters/lexicographic.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/sorters/lexicographic.rs @@ -37,20 +37,17 @@ pub fn new_sorter(sorters: Vec) -> impl Sorter { #[cfg(test)] mod tests { + use matrix_sdk::test_utils::logged_in_client_with_server; use matrix_sdk_test::async_test; use ruma::room_id; - use super::{ - super::super::filters::{client_and_server_prelude, new_rooms}, - *, - }; + use super::{super::super::filters::new_rooms, *}; #[async_test] async fn test_with_zero_sorter() { - let (client, server, sliding_sync) = client_and_server_prelude().await; + let (client, server) = logged_in_client_with_server().await; let [room_a, room_b] = - new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server, &sliding_sync) - .await; + new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server).await; let or = new_sorter(vec![]); @@ -59,10 +56,9 @@ mod tests { #[async_test] async fn test_with_one_sorter() { - let (client, server, sliding_sync) = client_and_server_prelude().await; + let (client, server) = logged_in_client_with_server().await; let [room_a, room_b] = - new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server, &sliding_sync) - .await; + new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server).await; let sorter_1 = |_: &_, _: &_| Ordering::Less; let or = new_sorter(vec![Box::new(sorter_1)]); @@ -72,10 +68,9 @@ mod tests { #[async_test] async fn test_with_two_sorters() { - let (client, server, sliding_sync) = client_and_server_prelude().await; + let (client, server) = logged_in_client_with_server().await; let [room_a, room_b] = - new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server, &sliding_sync) - .await; + new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server).await; let sorter_1 = |_: &_, _: &_| Ordering::Equal; let sorter_2 = |_: &_, _: &_| Ordering::Greater; @@ -86,10 +81,9 @@ mod tests { #[async_test] async fn test_with_more_sorters() { - let (client, server, sliding_sync) = client_and_server_prelude().await; + let (client, server) = logged_in_client_with_server().await; let [room_a, room_b] = - new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server, &sliding_sync) - .await; + new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server).await; let sorter_1 = |_: &_, _: &_| Ordering::Equal; let sorter_2 = |_: &_, _: &_| Ordering::Equal; diff --git a/crates/matrix-sdk-ui/src/room_list_service/sorters/name.rs b/crates/matrix-sdk-ui/src/room_list_service/sorters/name.rs index 17138480e8e..1bcdaf0fa9e 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/sorters/name.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/sorters/name.rs @@ -47,20 +47,17 @@ pub fn new_sorter() -> impl Sorter { #[cfg(test)] mod tests { + use matrix_sdk::test_utils::logged_in_client_with_server; use matrix_sdk_test::async_test; use ruma::room_id; - use super::{ - super::super::filters::{client_and_server_prelude, new_rooms}, - *, - }; + use super::{super::super::filters::new_rooms, *}; #[async_test] async fn test_with_two_names() { - let (client, server, sliding_sync) = client_and_server_prelude().await; + let (client, server) = logged_in_client_with_server().await; let [room_a, room_b] = - new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server, &sliding_sync) - .await; + new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server).await; // `room_a` has a “greater name” than `room_b`. { @@ -92,10 +89,9 @@ mod tests { #[async_test] async fn test_with_one_name() { - let (client, server, sliding_sync) = client_and_server_prelude().await; + let (client, server) = logged_in_client_with_server().await; let [room_a, room_b] = - new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server, &sliding_sync) - .await; + new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server).await; // `room_a` has a name, `room_b` has no name. { @@ -114,10 +110,9 @@ mod tests { #[async_test] async fn test_with_zero_name() { - let (client, server, sliding_sync) = client_and_server_prelude().await; + let (client, server) = logged_in_client_with_server().await; let [room_a, room_b] = - new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server, &sliding_sync) - .await; + new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server).await; // `room_a` and `room_b` has no name. { diff --git a/crates/matrix-sdk-ui/src/room_list_service/sorters/recency.rs b/crates/matrix-sdk-ui/src/room_list_service/sorters/recency.rs index c15a46d5047..82d8936083e 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/sorters/recency.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/sorters/recency.rs @@ -76,20 +76,17 @@ pub fn new_sorter() -> impl Sorter { #[cfg(test)] mod tests { + use matrix_sdk::test_utils::logged_in_client_with_server; use matrix_sdk_test::async_test; use ruma::room_id; - use super::{ - super::super::filters::{client_and_server_prelude, new_rooms}, - *, - }; + use super::{super::super::filters::new_rooms, *}; #[async_test] async fn test_with_two_recency_stamps() { - let (client, server, sliding_sync) = client_and_server_prelude().await; + let (client, server) = logged_in_client_with_server().await; let [room_a, room_b] = - new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server, &sliding_sync) - .await; + new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server).await; // `room_a` has an older recency stamp than `room_b`. { @@ -117,10 +114,9 @@ mod tests { #[async_test] async fn test_with_one_recency_stamp() { - let (client, server, sliding_sync) = client_and_server_prelude().await; + let (client, server) = logged_in_client_with_server().await; let [room_a, room_b] = - new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server, &sliding_sync) - .await; + new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server).await; // `room_a` has a recency stamp, `room_b` has no recency stamp. { @@ -139,10 +135,9 @@ mod tests { #[async_test] async fn test_with_zero_recency_stamp() { - let (client, server, sliding_sync) = client_and_server_prelude().await; + let (client, server) = logged_in_client_with_server().await; let [room_a, room_b] = - new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server, &sliding_sync) - .await; + new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server).await; // `room_a` and `room_b` has no recency stamp. { diff --git a/crates/matrix-sdk-ui/tests/integration/room_list_service.rs b/crates/matrix-sdk-ui/tests/integration/room_list_service.rs index a1ca670a288..b6fe8177e12 100644 --- a/crates/matrix-sdk-ui/tests/integration/room_list_service.rs +++ b/crates/matrix-sdk-ui/tests/integration/room_list_service.rs @@ -2426,7 +2426,7 @@ async fn test_room_timeline() -> Result<(), Error> { mock_encryption_state(&server, false).await; let room = room_list.room(room_id)?; - room.init_timeline_with_builder(room.default_room_timeline_builder().await.unwrap()).await?; + room.init_timeline_with_builder(room.default_room_timeline_builder().unwrap()).await?; let timeline = room.timeline().unwrap(); let (previous_timeline_items, mut timeline_items_stream) = timeline.subscribe().await; @@ -2491,7 +2491,7 @@ async fn test_room_empty_timeline() { // The room wasn't synced, but it will be available let room = room_list.room(&room_id).unwrap(); - let timeline = room.default_room_timeline_builder().await.unwrap().build().await.unwrap(); + let timeline = room.default_room_timeline_builder().unwrap().build().await.unwrap(); let (prev_items, _) = timeline.subscribe().await; // However, since the room wasn't synced its timeline won't have any initial @@ -2528,7 +2528,7 @@ async fn test_room_latest_event() -> Result<(), Error> { }; let room = room_list.room(room_id)?; - room.init_timeline_with_builder(room.default_room_timeline_builder().await.unwrap()).await?; + room.init_timeline_with_builder(room.default_room_timeline_builder().unwrap()).await?; // The latest event does not exist. assert!(room.latest_event().await.is_none()); @@ -2862,7 +2862,7 @@ async fn test_multiple_timeline_init() { // Get a RoomListService::Room, initialize the timeline, start a pagination. let room = room_list.room(room_id).unwrap(); - let builder = room.default_room_timeline_builder().await.unwrap(); + let builder = room.default_room_timeline_builder().unwrap(); room.init_timeline_with_builder(builder).await.unwrap(); let timeline = room.timeline().unwrap(); @@ -2878,6 +2878,6 @@ async fn test_multiple_timeline_init() { task.abort(); // A new timeline for the same room can still be constructed. - let builder = room.default_room_timeline_builder().await.unwrap(); + let builder = room.default_room_timeline_builder().unwrap(); room.init_timeline_with_builder(builder).await.unwrap(); } diff --git a/crates/matrix-sdk-ui/tests/integration/timeline/edit.rs b/crates/matrix-sdk-ui/tests/integration/timeline/edit.rs index d07af71056f..ab61add6c3e 100644 --- a/crates/matrix-sdk-ui/tests/integration/timeline/edit.rs +++ b/crates/matrix-sdk-ui/tests/integration/timeline/edit.rs @@ -647,75 +647,6 @@ async fn test_send_edit_poll() { server.verify().await; } -#[async_test] -async fn test_send_edit_when_timeline_is_clear() { - let server = MatrixMockServer::new().await; - let client = server.client_builder().build().await; - - let room_id = room_id!("!a98sd12bjh:example.org"); - let room = server.sync_joined_room(&client, room_id).await; - - server.mock_room_state_encryption().plain().mount().await; - - let timeline = room.timeline().await.unwrap(); - let (_, mut timeline_stream) = - timeline.subscribe_filter_map(|item| item.as_event().cloned()).await; - - let f = EventFactory::new(); - let raw_original_event = f - .text_msg("Hello, World!") - .sender(client.user_id().unwrap()) - .event_id(event_id!("$original_event")) - .into_raw_sync(); - - server - .sync_room( - &client, - JoinedRoomBuilder::new(room_id).add_timeline_event(raw_original_event.clone()), - ) - .await; - - let hello_world_item = - assert_next_matches!(timeline_stream, VectorDiff::PushBack { value } => value); - let hello_world_message = hello_world_item.content().as_message().unwrap(); - assert!(!hello_world_message.is_edited()); - assert!(hello_world_item.is_editable()); - - // Receive a limited (gappy) sync for this room, which will clear the timeline… - // - // TODO: …until the event cache storage is enabled by default, a time where - // we'll be able to get rid of this test entirely (or update its - // expectations). - - server.sync_room(&client, JoinedRoomBuilder::new(room_id).set_timeline_limited()).await; - client.event_cache().empty_immutable_cache().await; - - yield_now().await; - assert_next_matches!(timeline_stream, VectorDiff::Clear); - - // Sending the edit will fail, since the edited event isn't in the timeline - // anymore. - assert_matches!( - timeline - .edit( - &hello_world_item.identifier(), - EditedContent::RoomMessage(RoomMessageEventContentWithoutRelation::text_plain( - "Hello, Room!", - )), - ) - .await, - Err(Error::EventNotInTimeline(TimelineEventItemId::EventId(event_id))) => { - assert_eq!(hello_world_item.event_id().unwrap(), event_id); - } - ); - - // The response to the mocked endpoint does not generate further timeline - // updates, so just wait for a bit before verifying that the endpoint was - // called. - sleep(Duration::from_millis(200)).await; - assert!(timeline_stream.next().now_or_never().is_none()); -} - #[async_test] async fn test_edit_local_echo_with_unsupported_content() { let room_id = room_id!("!a98sd12bjh:example.org"); diff --git a/crates/matrix-sdk-ui/tests/integration/timeline/pagination.rs b/crates/matrix-sdk-ui/tests/integration/timeline/pagination.rs index a796fc740da..90990feec57 100644 --- a/crates/matrix-sdk-ui/tests/integration/timeline/pagination.rs +++ b/crates/matrix-sdk-ui/tests/integration/timeline/pagination.rs @@ -498,9 +498,9 @@ async fn test_timeline_reset_while_paginating() { // field. assert!(hit_start); - // No events in back-pagination responses, date divider + event from latest - // sync is present - assert_eq!(timeline.items().await.len(), 2); + // No events in back-pagination responses, date divider + both events from + // syncs are present + assert_eq!(timeline.items().await.len(), 3); // Make sure both pagination mocks were called server.verify().await; diff --git a/crates/matrix-sdk/src/event_cache/mod.rs b/crates/matrix-sdk/src/event_cache/mod.rs index d41c54d88bd..39fd2ce4167 100644 --- a/crates/matrix-sdk/src/event_cache/mod.rs +++ b/crates/matrix-sdk/src/event_cache/mod.rs @@ -168,23 +168,6 @@ impl EventCache { } } - /// Enable storing updates to storage, and reload events from storage. - /// - /// Has an effect only the first time it's called. It's safe to call it - /// multiple times. - pub fn enable_storage(&self) -> Result<()> { - let _ = self.inner.store.get_or_try_init::<_, EventCacheError>(|| { - let client = self.inner.client()?; - Ok(client.event_cache_store().clone()) - })?; - Ok(()) - } - - /// Check whether the storage is enabled or not. - pub fn has_storage(&self) -> bool { - self.inner.has_storage() - } - /// Starts subscribing the [`EventCache`] to sync responses, if not done /// before. /// @@ -193,6 +176,13 @@ impl EventCache { pub fn subscribe(&self) -> Result<()> { let client = self.inner.client()?; + // Initialize storage. + let _ = self.inner.store.get_or_try_init::<_, EventCacheError>(|| { + let client = self.inner.client()?; + Ok(client.event_cache_store().clone()) + })?; + + // Initialize the drop handles. let _ = self.inner.drop_handles.get_or_init(|| { // Spawn the task that will listen to all the room updates at once. let listen_updates_task = spawn(Self::listen_task( @@ -314,42 +304,6 @@ impl EventCache { Ok((room, drop_handles)) } - - /// Add an initial set of events to the event cache, reloaded from a cache. - /// - /// TODO: temporary for API compat, as the event cache should take care of - /// its own store. - #[instrument(skip(self, events))] - pub async fn add_initial_events( - &self, - room_id: &RoomId, - events: Vec, - prev_batch: Option, - ) -> Result<()> { - // If the event cache's storage has been enabled, do nothing. - if self.inner.has_storage() { - return Ok(()); - } - - let room_cache = self.inner.for_room(room_id).await?; - - // If the linked chunked already has at least one event, ignore this request, as - // it should happen at most once per room. - if !room_cache.inner.state.read().await.events().is_empty() { - return Ok(()); - } - - // We could have received events during a previous sync; remove them all, since - // we can't know where to insert the "initial events" with respect to - // them. - - room_cache - .inner - .replace_all_events_by(events, prev_batch, Default::default(), Default::default()) - .await?; - - Ok(()) - } } type AllEventsMap = BTreeMap; @@ -523,11 +477,6 @@ impl EventCacheInner { self.client.get().ok_or(EventCacheError::ClientDropped) } - /// Has persistent storage been enabled for the event cache? - fn has_storage(&self) -> bool { - self.store.get().is_some() - } - /// Clears all the room's data. async fn clear_all_rooms(&self) -> Result<()> { // Note: one must NOT clear the `by_room` map, because if something subscribed @@ -560,9 +509,7 @@ impl EventCacheInner { for (room_id, left_room_update) in updates.leave { let room = self.for_room(&room_id).await?; - if let Err(err) = - room.inner.handle_left_room_update(self.has_storage(), left_room_update).await - { + if let Err(err) = room.inner.handle_left_room_update(left_room_update).await { // Non-fatal error, try to continue to the next room. error!("handling left room update: {err}"); } @@ -572,9 +519,7 @@ impl EventCacheInner { for (room_id, joined_room_update) in updates.join { let room = self.for_room(&room_id).await?; - if let Err(err) = - room.inner.handle_joined_room_update(self.has_storage(), joined_room_update).await - { + if let Err(err) = room.inner.handle_joined_room_update(joined_room_update).await { // Non-fatal error, try to continue to the next room. error!("handling joined room update: {err}"); } @@ -752,10 +697,7 @@ mod tests { room_event_cache .inner - .handle_joined_room_update( - event_cache.inner.has_storage(), - JoinedRoomUpdate { account_data, ..Default::default() }, - ) + .handle_joined_room_update(JoinedRoomUpdate { account_data, ..Default::default() }) .await .unwrap(); @@ -870,28 +812,4 @@ mod tests { assert!(room_event_cache.event(event_id).await.is_none()); assert!(event_cache.event(event_id).await.is_none()); } - - #[async_test] - async fn test_add_initial_events() { - // TODO: remove this test when the event cache uses its own persistent storage. - let client = logged_in_client(None).await; - let room_id = room_id!("!galette:saucisse.bzh"); - - let event_cache = client.event_cache(); - event_cache.subscribe().unwrap(); - - let f = EventFactory::new().room(room_id).sender(user_id!("@ben:saucisse.bzh")); - event_cache - .add_initial_events(room_id, vec![f.text_msg("hey").into()], None) - .await - .unwrap(); - - client.base_client().get_or_create_room(room_id, matrix_sdk_base::RoomState::Joined); - let room = client.get_room(room_id).unwrap(); - - let (room_event_cache, _drop_handles) = room.event_cache().await.unwrap(); - let (initial_events, _) = room_event_cache.subscribe().await.unwrap(); - // `add_initial_events` had an effect. - assert_eq!(initial_events.len(), 1); - } } diff --git a/crates/matrix-sdk/src/event_cache/room/events.rs b/crates/matrix-sdk/src/event_cache/room/events.rs index 516432304a6..ace1f58c281 100644 --- a/crates/matrix-sdk/src/event_cache/room/events.rs +++ b/crates/matrix-sdk/src/event_cache/room/events.rs @@ -77,11 +77,6 @@ impl RoomEvents { Self { chunks, chunks_updates_as_vectordiffs, deduplicator } } - /// Returns whether the room has at least one event. - pub fn is_empty(&self) -> bool { - self.chunks.num_items() == 0 - } - /// Clear all events. /// /// All events, all gaps, everything is dropped, move into the void, into diff --git a/crates/matrix-sdk/src/event_cache/room/mod.rs b/crates/matrix-sdk/src/event_cache/room/mod.rs index e7f95058090..b3940f63b0f 100644 --- a/crates/matrix-sdk/src/event_cache/room/mod.rs +++ b/crates/matrix-sdk/src/event_cache/room/mod.rs @@ -278,13 +278,8 @@ impl RoomEventCacheInner { } } - pub(super) async fn handle_joined_room_update( - &self, - has_storage: bool, - updates: JoinedRoomUpdate, - ) -> Result<()> { + pub(super) async fn handle_joined_room_update(&self, updates: JoinedRoomUpdate) -> Result<()> { self.handle_timeline( - has_storage, updates.timeline, updates.ephemeral.clone(), updates.ambiguity_changes, @@ -298,88 +293,33 @@ impl RoomEventCacheInner { async fn handle_timeline( &self, - has_storage: bool, timeline: Timeline, ephemeral_events: Vec>, ambiguity_changes: BTreeMap, ) -> Result<()> { - if !has_storage && timeline.limited { - // Ideally we'd try to reconcile existing events against those received in the - // timeline, but we're not there yet. In the meanwhile, clear the - // items from the room. TODO: implement Smart Matching™. - trace!("limited timeline, clearing all previous events and pushing new events"); - - self.replace_all_events_by( - timeline.events, - timeline.prev_batch, - ephemeral_events, - ambiguity_changes, - ) - .await?; - } else { - // Add all the events to the backend. - trace!("adding new events"); - - // Only keep the previous-batch token if we have a limited timeline; otherwise, - // we know about all the events, and we don't need to back-paginate, - // so we wouldn't make use of the given previous-batch token. - let prev_batch = if timeline.limited { timeline.prev_batch } else { None }; - - let mut state = self.state.write().await; - self.append_events_locked( - &mut state, - timeline.events, - prev_batch, - ephemeral_events, - ambiguity_changes, - ) - .await?; - } - - Ok(()) - } + // Add all the events to the backend. + trace!("adding new events"); - pub(super) async fn handle_left_room_update( - &self, - has_storage: bool, - updates: LeftRoomUpdate, - ) -> Result<()> { - self.handle_timeline(has_storage, updates.timeline, Vec::new(), updates.ambiguity_changes) - .await?; - Ok(()) - } + // Only keep the previous-batch token if we have a limited timeline; otherwise, + // we know about all the events, and we don't need to back-paginate, + // so we wouldn't make use of the given previous-batch token. + let prev_batch = if timeline.limited { timeline.prev_batch } else { None }; - /// Remove existing events, and append a set of events to the room cache and - /// storage, notifying observers. - pub(super) async fn replace_all_events_by( - &self, - sync_timeline_events: Vec, - prev_batch: Option, - ephemeral_events: Vec>, - ambiguity_changes: BTreeMap, - ) -> Result<()> { - // Acquire the lock. let mut state = self.state.write().await; - - // Reset the room's state. - state.reset().await?; - - // Propagate to observers. - let _ = self.sender.send(RoomEventCacheUpdate::Clear); - - // Push the new events. self.append_events_locked( &mut state, - sync_timeline_events, - prev_batch.clone(), + timeline.events, + prev_batch, ephemeral_events, ambiguity_changes, ) .await?; - // Reset the paginator status to initial. - self.paginator.set_idle_state(PaginatorState::Initial, prev_batch, None)?; + Ok(()) + } + pub(super) async fn handle_left_room_update(&self, updates: LeftRoomUpdate) -> Result<()> { + self.handle_timeline(updates.timeline, Vec::new(), updates.ambiguity_changes).await?; Ok(()) } @@ -1092,7 +1032,6 @@ mod tests { // Don't forget to subscribe and like^W enable storage! event_cache.subscribe().unwrap(); - event_cache.enable_storage().unwrap(); client.base_client().get_or_create_room(room_id, matrix_sdk_base::RoomState::Joined); let room = client.get_room(room_id).unwrap(); @@ -1108,7 +1047,7 @@ mod tests { room_event_cache .inner - .handle_joined_room_update(true, JoinedRoomUpdate { timeline, ..Default::default() }) + .handle_joined_room_update(JoinedRoomUpdate { timeline, ..Default::default() }) .await .unwrap(); @@ -1164,7 +1103,6 @@ mod tests { // Don't forget to subscribe and like^W enable storage! event_cache.subscribe().unwrap(); - event_cache.enable_storage().unwrap(); client.base_client().get_or_create_room(room_id, matrix_sdk_base::RoomState::Joined); let room = client.get_room(room_id).unwrap(); @@ -1181,7 +1119,7 @@ mod tests { room_event_cache .inner - .handle_joined_room_update(true, JoinedRoomUpdate { timeline, ..Default::default() }) + .handle_joined_room_update(JoinedRoomUpdate { timeline, ..Default::default() }) .await .unwrap(); @@ -1297,7 +1235,6 @@ mod tests { // Don't forget to subscribe and like^W enable storage! event_cache.subscribe().unwrap(); - event_cache.enable_storage().unwrap(); client.base_client().get_or_create_room(room_id, matrix_sdk_base::RoomState::Joined); let room = client.get_room(room_id).unwrap(); @@ -1408,7 +1345,6 @@ mod tests { // Don't forget to subscribe and like^W enable storage! event_cache.subscribe().unwrap(); - event_cache.enable_storage().unwrap(); client.base_client().get_or_create_room(room_id, matrix_sdk_base::RoomState::Joined); let room = client.get_room(room_id).unwrap(); @@ -1426,7 +1362,7 @@ mod tests { let timeline = Timeline { limited: false, prev_batch: None, events: vec![ev2] }; room_event_cache .inner - .handle_joined_room_update(true, JoinedRoomUpdate { timeline, ..Default::default() }) + .handle_joined_room_update(JoinedRoomUpdate { timeline, ..Default::default() }) .await .unwrap(); @@ -1477,7 +1413,6 @@ mod tests { // Don't forget to subscribe and like^W enable storage! event_cache.subscribe().unwrap(); - event_cache.enable_storage().unwrap(); client.base_client().get_or_create_room(room_id, matrix_sdk_base::RoomState::Joined); let room = client.get_room(room_id).unwrap(); @@ -1506,9 +1441,6 @@ mod tests { let event_cache = client.event_cache(); event_cache.subscribe().unwrap(); - let has_storage = true; // for testing purposes only - event_cache.enable_storage().unwrap(); - client.base_client().get_or_create_room(room_id, matrix_sdk_base::RoomState::Joined); let room = client.get_room(room_id).unwrap(); let (room_event_cache, _drop_handles) = room.event_cache().await.unwrap(); @@ -1519,17 +1451,14 @@ mod tests { // prev-batch token. room_event_cache .inner - .handle_joined_room_update( - has_storage, - JoinedRoomUpdate { - timeline: Timeline { - limited: true, - prev_batch: Some("raclette".to_owned()), - events: vec![f.text_msg("hey yo").into_sync()], - }, - ..Default::default() + .handle_joined_room_update(JoinedRoomUpdate { + timeline: Timeline { + limited: true, + prev_batch: Some("raclette".to_owned()), + events: vec![f.text_msg("hey yo").into_sync()], }, - ) + ..Default::default() + }) .await .unwrap(); @@ -1555,17 +1484,14 @@ mod tests { // this time. room_event_cache .inner - .handle_joined_room_update( - has_storage, - JoinedRoomUpdate { - timeline: Timeline { - limited: false, - prev_batch: Some("fondue".to_owned()), - events: vec![f.text_msg("sup").into_sync()], - }, - ..Default::default() + .handle_joined_room_update(JoinedRoomUpdate { + timeline: Timeline { + limited: false, + prev_batch: Some("fondue".to_owned()), + events: vec![f.text_msg("sup").into_sync()], }, - ) + ..Default::default() + }) .await .unwrap(); diff --git a/crates/matrix-sdk/tests/integration/event_cache.rs b/crates/matrix-sdk/tests/integration/event_cache.rs index 602c3732838..28cebfd8240 100644 --- a/crates/matrix-sdk/tests/integration/event_cache.rs +++ b/crates/matrix-sdk/tests/integration/event_cache.rs @@ -7,6 +7,7 @@ use std::{ use assert_matches::assert_matches; use assert_matches2::assert_let; use eyeball_im::VectorDiff; +use futures_util::FutureExt as _; use matrix_sdk::{ assert_let_timeout, assert_next_matches_with_timeout, deserialized_responses::SyncTimelineEvent, @@ -617,13 +618,14 @@ async fn test_reset_while_backpaginating() { let f = EventFactory::new().room(room_id).sender(user_id!("@a:b.c")); + // After sync: Timeline = [$2]. server .sync_room( &client, JoinedRoomBuilder::new(room_id) // Note to self: a timeline must have at least single event to be properly // serialized. - .add_timeline_event(f.text_msg("heyo").into_raw_sync()) + .add_timeline_event(f.text_msg("$2").event_id(event_id!("$2")).into_raw_sync()) .set_timeline_prev_batch("first_backpagination".to_owned()) .set_timeline_limited(), ) @@ -651,12 +653,15 @@ async fn test_reset_while_backpaginating() { // - a backpagination will be sent concurrently. // // So events have to happen in this order: - // - the backpagination request is sent, with a prev-batch A + // - the backpagination request is sent, with a prev-batch + // `first_backpagination`. // - the sync endpoint returns *after* the backpagination started, before the - // backpagination ends - // - the backpagination ends, with a prev-batch token that's now stale. + // backpagination ends; it returns a new event, and a new backpagination token + // `second_backpagination`. + // - the backpagination ends, with a prev-batch token that's now not the latest. // - // The backpagination should result in an unknown-token-error. + // The backpagination should succeed, and insert the event back-paginated from + // `first_backpagination` at its rightful location in the timeline. // Mock the first back-pagination request, with a delay. server @@ -665,7 +670,7 @@ async fn test_reset_while_backpaginating() { .respond_with( ResponseTemplate::new(200) .set_body_json(json!({ - "chunk": vec![f.text_msg("lalala").into_raw_timeline()], + "chunk": vec![f.text_msg("$1").event_id(event_id!("$1")).into_raw_timeline()], "start": "t392-516_47314_0_7_1_1_1_11444_1", })) // This is why we don't use `server.mock_room_messages()`. @@ -675,21 +680,6 @@ async fn test_reset_while_backpaginating() { .mount() .await; - // Mock the second back-pagination request, that will be hit after the reset - // caused by the sync. - server - .mock_room_messages() - .from("second_backpagination") - .ok( - "start-token-unused".to_owned(), - Some("third_backpagination".to_owned()), - vec![f.text_msg("finally!").into_raw_timeline()], - Vec::new(), - ) - .mock_once() - .mount() - .await; - // Run the pagination! let pagination = room_event_cache.pagination(); @@ -704,7 +694,7 @@ async fn test_reset_while_backpaginating() { .run_backwards(20, |outcome, timeline_has_been_reset| { assert_matches!( timeline_has_been_reset, - TimelineHasBeenResetWhilePaginating::Yes + TimelineHasBeenResetWhilePaginating::No ); ready(ControlFlow::Break(outcome)) @@ -713,14 +703,15 @@ async fn test_reset_while_backpaginating() { } }); - // Receive the sync response (which clears the timeline). + // Receive the sync response. It doesn't clear the timeline, because we have + // persistent storage. server .sync_room( &client, JoinedRoomBuilder::new(room_id) // Note to self: a timeline must have at least single event to be properly // serialized. - .add_timeline_event(f.text_msg("heyo").into_raw_sync()) + .add_timeline_event(f.text_msg("$3").event_id(event_id!("$3")).into_raw_sync()) .set_timeline_prev_batch("second_backpagination".to_owned()) .set_timeline_limited(), ) @@ -728,42 +719,36 @@ async fn test_reset_while_backpaginating() { let outcome = backpagination.await.expect("join failed").unwrap(); - // Backpagination will automatically restart, so eventually we get the events. + // Backpagination must return some events. let BackPaginationOutcome { events, .. } = outcome; assert!(!events.is_empty()); - // Now if we retrieve the oldest token, it's set to something else. + // If we retrieve the most recent token, it's now `second_backpagination`; this + // previous-batch token does not get consumed. assert_let!( PaginationToken::HasMore(second_token) = pagination.get_or_wait_for_token(None).await ); assert!(first_token != second_token); - assert_eq!(second_token, "third_backpagination"); - - // Assert the updates as diffs. - - // Being cleared from the reset. - assert_let_timeout!(Ok(RoomEventCacheUpdate::Clear) = room_stream.recv()); + assert_eq!(second_token, "second_backpagination"); + // Receive the sync update. assert_let_timeout!( Ok(RoomEventCacheUpdate::UpdateTimelineEvents { diffs, .. }) = room_stream.recv() ); - assert_eq!(diffs.len(), 2); - // The clear, again. - assert_matches!(&diffs[0], VectorDiff::Clear); + assert_eq!(diffs.len(), 1); // The event from the sync. - assert_matches!(&diffs[1], VectorDiff::Append { values: events } => { + assert_matches!(&diffs[0], VectorDiff::Append { values: events } => { assert_eq!(events.len(), 1); - assert_event_matches_msg(&events[0], "heyo"); + assert_event_matches_msg(&events[0], "$3"); }); + // Receive the back-pagination update. assert_let_timeout!( Ok(RoomEventCacheUpdate::UpdateTimelineEvents { diffs, .. }) = room_stream.recv() ); assert_eq!(diffs.len(), 1); - // The event from the pagination. - assert_matches!(&diffs[0], VectorDiff::Insert { index, value: event } => { - assert_eq!(*index, 0); - assert_event_matches_msg(event, "finally!"); + assert_matches!(&diffs[0], VectorDiff::Insert { index: 0, value: event } => { + assert_event_matches_msg(event, "$1"); }); assert!(room_stream.is_empty()); @@ -896,17 +881,12 @@ async fn test_limited_timeline_resets_pagination() { // When a limited sync comes back from the server, server.sync_room(&client, JoinedRoomBuilder::new(room_id).set_timeline_limited()).await; - // We receive an update about the limited timeline. - assert_let_timeout!(Ok(RoomEventCacheUpdate::Clear) = room_stream.recv()); - - // The paginator state is reset: status set to Initial, hasn't hit the timeline - // start. - assert!(!pagination.hit_timeline_start()); - assert_eq!(pagination_status.get(), PaginatorState::Initial); - - // We receive an update about the paginator status. - assert_next_matches_with_timeout!(pagination_status, PaginatorState::Initial); + // Since we have storage, the update has no effect. + assert!(pagination.hit_timeline_start()); + assert_eq!(pagination_status.get(), PaginatorState::Idle); + // We're done. + assert!(pagination_status.next().now_or_never().is_none()); assert!(room_stream.is_empty()); } @@ -919,7 +899,6 @@ async fn test_limited_timeline_with_storage() { // Don't forget to subscribe and like^W enable storage! event_cache.subscribe().unwrap(); - event_cache.enable_storage().unwrap(); let room_id = room_id!("!galette:saucisse.bzh"); let room = server.sync_joined_room(&client, room_id).await; @@ -1168,7 +1147,6 @@ async fn test_no_gap_stored_after_deduplicated_sync() { // Immediately subscribe the event cache to sync updates. event_cache.subscribe().unwrap(); - event_cache.enable_storage().unwrap(); let room_id = room_id!("!omelette:fromage.fr"); @@ -1251,7 +1229,6 @@ async fn test_no_gap_stored_after_deduplicated_backpagination() { // Immediately subscribe the event cache to sync updates. event_cache.subscribe().unwrap(); - event_cache.enable_storage().unwrap(); let room_id = room_id!("!omelette:fromage.fr"); @@ -1388,7 +1365,6 @@ async fn test_dont_delete_gap_that_wasnt_inserted() { // Immediately subscribe the event cache to sync updates. event_cache.subscribe().unwrap(); - event_cache.enable_storage().unwrap(); let room_id = room_id!("!omelette:fromage.fr"); diff --git a/labs/multiverse/src/main.rs b/labs/multiverse/src/main.rs index 9da33ecf578..56cc7a88755 100644 --- a/labs/multiverse/src/main.rs +++ b/labs/multiverse/src/main.rs @@ -66,7 +66,6 @@ async fn main() -> anyhow::Result<()> { let ec = client.event_cache(); ec.subscribe().unwrap(); - ec.enable_storage().unwrap(); init_error_hooks()?; let terminal = init_terminal()?; @@ -251,7 +250,7 @@ impl App { .filter(|room| !previous_ui_rooms.contains_key(room.room_id())) { // Initialize the timeline. - let builder = match ui_room.default_room_timeline_builder().await { + let builder = match ui_room.default_room_timeline_builder() { Ok(builder) => builder, Err(err) => { error!("error when getting default timeline builder: {err}");