From 32cc477f5465530d5b9cdbb8da0cece33c0151b2 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 30 Nov 2022 10:21:24 +0100 Subject: [PATCH] refactor(sdk): Remove media caching from in-memory state store --- Cargo.lock | 10 - crates/matrix-sdk-base/Cargo.toml | 1 - .../src/store/integration_tests.rs | 1349 +++++++++-------- .../matrix-sdk-base/src/store/memory_store.rs | 40 +- .../matrix-sdk-indexeddb/src/state_store.rs | 4 +- crates/matrix-sdk-sled/src/state_store.rs | 4 +- crates/matrix-sdk/tests/integration/client.rs | 9 +- 7 files changed, 695 insertions(+), 722 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c73f0e9f8..4e1fd3774 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2529,15 +2529,6 @@ dependencies = [ "thread-id", ] -[[package]] -name = "lru" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6e8aaa3f231bb4bd57b84b2d5dc3ae7f350265df8aa96492e0bc394a1571909" -dependencies = [ - "hashbrown", -] - [[package]] name = "maplit" version = "1.0.2" @@ -2659,7 +2650,6 @@ dependencies = [ "futures-signals", "futures-util", "http", - "lru", "matrix-sdk-common", "matrix-sdk-crypto", "matrix-sdk-store-encryption", diff --git a/crates/matrix-sdk-base/Cargo.toml b/crates/matrix-sdk-base/Cargo.toml index 807be807e..20e226013 100644 --- a/crates/matrix-sdk-base/Cargo.toml +++ b/crates/matrix-sdk-base/Cargo.toml @@ -34,7 +34,6 @@ futures-core = "0.3.21" futures-signals = { version = "0.3.30", default-features = false } futures-util = { version = "0.3.21", default-features = false } http = { version = "0.2.6", optional = true } -lru = "0.8.0" matrix-sdk-common = { version = "0.6.0", path = "../matrix-sdk-common" } matrix-sdk-crypto = { version = "0.6.0", path = "../matrix-sdk-crypto", optional = true } matrix-sdk-store-encryption = { version = "0.2.0", path = "../matrix-sdk-store-encryption" } diff --git a/crates/matrix-sdk-base/src/store/integration_tests.rs b/crates/matrix-sdk-base/src/store/integration_tests.rs index a452c74d3..98cee3b79 100644 --- a/crates/matrix-sdk-base/src/store/integration_tests.rs +++ b/crates/matrix-sdk-base/src/store/integration_tests.rs @@ -28,556 +28,17 @@ #[allow(unused_macros, unused_extern_crates)] #[macro_export] macro_rules! statestore_integration_tests { - () => { + (with_media_tests) => { mod statestore_integration_tests { - use std::{ - collections::{BTreeMap, BTreeSet}, - sync::Arc, - }; + $crate::statestore_integration_tests!(@inner); - use matrix_sdk_test::{async_test, test_json}; use ruma::{ api::client::media::get_content_thumbnail::v3::Method, - event_id, - events::{ - presence::PresenceEvent, - receipt::ReceiptType, - room::{ - member::{ - MembershipState, OriginalSyncRoomMemberEvent, RoomMemberEventContent, - RoomMemberUnsigned, StrippedRoomMemberEvent, SyncRoomMemberEvent, - }, - power_levels::RoomPowerLevelsEventContent, - MediaSource, - topic::{RoomTopicEventContent, OriginalRoomTopicEvent, RedactedRoomTopicEvent}, - }, - AnyEphemeralRoomEventContent, AnyGlobalAccountDataEvent, - AnyRoomAccountDataEvent, AnyStrippedStateEvent, AnySyncEphemeralRoomEvent, - AnySyncStateEvent, GlobalAccountDataEventType, RoomAccountDataEventType, - StateEventType, - }, - mxc_uri, room_id, - serde::Raw, - uint, user_id, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, RoomId, UserId, - }; - use serde_json::{json, Value as JsonValue}; - - use $crate::{ - media::{MediaFormat, MediaRequest, MediaThumbnailSize}, - store::{Result as StoreResult, StateChanges, StateStore, StateStoreExt}, - RoomInfo, RoomType, + events::room::MediaSource, + mxc_uri, uint, }; - use super::get_store; - - fn user_id() -> &'static UserId { - user_id!("@example:localhost") - } - pub(crate) fn invited_user_id() -> &'static UserId { - user_id!("@invited:localhost") - } - - pub(crate) fn room_id() -> &'static RoomId { - room_id!("!test:localhost") - } - - pub(crate) fn stripped_room_id() -> &'static RoomId { - room_id!("!stripped:localhost") - } - - pub(crate) fn first_receipt_event_id() -> &'static EventId { - event_id!("$example") - } - - /// Populate the given `StateStore`. - pub async fn populate_store(store: Arc) -> StoreResult<()> { - let mut changes = StateChanges::default(); - - let user_id = user_id(); - let invited_user_id = invited_user_id(); - let room_id = room_id(); - let stripped_room_id = stripped_room_id(); - - changes.sync_token = Some("t392-516_47314_0_7_1_1_1_11444_1".to_owned()); - - let presence_json: &JsonValue = &test_json::PRESENCE; - let presence_raw = - serde_json::from_value::>(presence_json.clone()).unwrap(); - let presence_event = presence_raw.deserialize().unwrap(); - changes.add_presence_event(presence_event, presence_raw); - - let pushrules_json: &JsonValue = &test_json::PUSH_RULES; - let pushrules_raw = serde_json::from_value::>( - pushrules_json.clone(), - ) - .unwrap(); - let pushrules_event = pushrules_raw.deserialize().unwrap(); - changes.add_account_data(pushrules_event, pushrules_raw); - - let mut room = RoomInfo::new(room_id, RoomType::Joined); - room.mark_as_left(); - - let tag_json: &JsonValue = &test_json::TAG; - let tag_raw = - serde_json::from_value::>(tag_json.clone()) - .unwrap(); - let tag_event = tag_raw.deserialize().unwrap(); - changes.add_room_account_data(room_id, tag_event, tag_raw); - - let name_json: &JsonValue = &test_json::NAME; - let name_raw = - serde_json::from_value::>(name_json.clone()).unwrap(); - let name_event = name_raw.deserialize().unwrap(); - room.handle_state_event(&name_event); - changes.add_state_event(room_id, name_event, name_raw); - - let topic_json: &JsonValue = &test_json::TOPIC; - let topic_raw = - serde_json::from_value::>(topic_json.clone()).expect("can create sync-state-event for topic"); - let topic_event = topic_raw.deserialize().expect("can deserialize raw topic"); - room.handle_state_event(&topic_event); - changes.add_state_event(room_id, topic_event, topic_raw); - - let mut room_ambiguity_map = BTreeMap::new(); - let mut room_profiles = BTreeMap::new(); - let mut room_members = BTreeMap::new(); - - let member_json: &JsonValue = &test_json::MEMBER; - let member_event: SyncRoomMemberEvent = - serde_json::from_value(member_json.clone()).unwrap(); - let displayname = - member_event.as_original().unwrap().content.displayname.clone().unwrap(); - room_ambiguity_map - .insert(displayname.clone(), BTreeSet::from([user_id.to_owned()])); - room_profiles.insert(user_id.to_owned(), (&member_event).into()); - room_members.insert(user_id.to_owned(), member_event); - - let member_state_raw = - serde_json::from_value::>(member_json.clone()).unwrap(); - let member_state_event = member_state_raw.deserialize().unwrap(); - changes.add_state_event(room_id, member_state_event, member_state_raw); - - let invited_member_json: &JsonValue = &test_json::MEMBER_INVITE; - // FIXME: Should be stripped room member event - let invited_member_event: SyncRoomMemberEvent = - serde_json::from_value(invited_member_json.clone()).unwrap(); - room_ambiguity_map - .entry(displayname) - .or_default() - .insert(invited_user_id.to_owned()); - room_profiles.insert(invited_user_id.to_owned(), (&invited_member_event).into()); - room_members.insert(invited_user_id.to_owned(), invited_member_event); - - let invited_member_state_raw = - serde_json::from_value::>(invited_member_json.clone()) - .unwrap(); - let invited_member_state_event = invited_member_state_raw.deserialize().unwrap(); - changes.add_state_event( - room_id, - invited_member_state_event, - invited_member_state_raw, - ); - - let receipt_json: &JsonValue = &test_json::READ_RECEIPT; - let receipt_event = - serde_json::from_value::(receipt_json.clone()) - .unwrap(); - let receipt_content = match receipt_event.content() { - AnyEphemeralRoomEventContent::Receipt(content) => content, - _ => panic!(), - }; - changes.add_receipts(room_id, receipt_content); - - changes.ambiguity_maps.insert(room_id.to_owned(), room_ambiguity_map); - changes.profiles.insert(room_id.to_owned(), room_profiles); - changes.members.insert(room_id.to_owned(), room_members); - changes.add_room(room); - - let mut stripped_room = RoomInfo::new(stripped_room_id, RoomType::Invited); - - let stripped_name_json: &JsonValue = &test_json::NAME_STRIPPED; - let stripped_name_raw = serde_json::from_value::>( - stripped_name_json.clone(), - ) - .unwrap(); - let stripped_name_event = stripped_name_raw.deserialize().unwrap(); - stripped_room.handle_stripped_state_event(&stripped_name_event); - changes.stripped_state.insert( - stripped_room_id.to_owned(), - BTreeMap::from([( - stripped_name_event.event_type(), - BTreeMap::from([( - stripped_name_event.state_key().to_owned(), - stripped_name_raw.clone(), - )]), - )]), - ); - - changes.add_stripped_room(stripped_room); - - let stripped_member_json: &JsonValue = &test_json::MEMBER_STRIPPED; - let stripped_member_event = - serde_json::from_value::(stripped_member_json.clone()) - .unwrap(); - changes.add_stripped_member(stripped_room_id, stripped_member_event); - - store.save_changes(&changes).await?; - Ok(()) - } - - fn power_level_event() -> Raw { - let content = RoomPowerLevelsEventContent::default(); - - let event = json!({ - "event_id": "$h29iv0s8:example.com", - "content": content, - "sender": user_id(), - "type": "m.room.power_levels", - "origin_server_ts": 0u64, - "state_key": "", - }); - - serde_json::from_value(event).unwrap() - } - - fn stripped_membership_event() -> StrippedRoomMemberEvent { - custom_stripped_membership_event(user_id()) - } - - fn custom_stripped_membership_event(user_id: &UserId) -> StrippedRoomMemberEvent { - StrippedRoomMemberEvent { - content: RoomMemberEventContent::new(MembershipState::Join), - sender: user_id.to_owned(), - state_key: user_id.to_owned(), - } - } - - fn membership_event() -> SyncRoomMemberEvent { - custom_membership_event(user_id(), event_id!("$h29iv0s8:example.com").to_owned()) - } - - fn custom_membership_event( - user_id: &UserId, - event_id: OwnedEventId, - ) -> SyncRoomMemberEvent { - SyncRoomMemberEvent::Original(OriginalSyncRoomMemberEvent { - event_id, - content: RoomMemberEventContent::new(MembershipState::Join), - sender: user_id.to_owned(), - origin_server_ts: MilliSecondsSinceUnixEpoch(198u32.into()), - state_key: user_id.to_owned(), - unsigned: RoomMemberUnsigned::default(), - }) - } - - #[async_test] - async fn test_topic_redaction() -> StoreResult<()> { - let room_id = room_id(); - let inner_store = get_store().await?; - - let store = Arc::new(inner_store); - populate_store(store.clone()).await?; - - assert!(store.get_sync_token().await?.is_some()); - assert_eq!( - store - .get_state_event_static::(room_id) - .await? - .expect("room topic found before redaction") - .deserialize_as::() - .expect("can deserialize room topic before redaction") - .content - .topic, - "😀" - ); - - let mut changes = StateChanges::default(); - - let redaction_json: &JsonValue = &test_json::TOPIC_REDACTION; - let redaction_evt = serde_json::from_value(redaction_json.clone()).expect("topic redaction event making works"); - - changes.add_redaction(room_id, redaction_evt); - store.save_changes(&changes).await?; - - match store - .get_state_event_static::(room_id) - .await? - .expect("room topic found before redaction") - .deserialize_as::() - { - Err(_) => { } // as expected - Ok(_) => panic!("Topic has not been redacted") - } - - let _ = store - .get_state_event_static::(room_id) - .await? - .expect("room topic found after redaction") - .deserialize_as::() - .expect("can deserialize room topic after redaction"); - - Ok(()) - } - - #[async_test] - async fn test_populate_store() -> StoreResult<()> { - let room_id = room_id(); - let user_id = user_id(); - let inner_store = get_store().await?; - - let store = Arc::new(inner_store); - populate_store(store.clone()).await?; - - assert!(store.get_sync_token().await?.is_some()); - assert!(store.get_presence_event(user_id).await?.is_some()); - assert_eq!(store.get_room_infos().await?.len(), 1, "Expected to find 1 room info"); - assert_eq!( - store.get_stripped_room_infos().await?.len(), - 1, - "Expected to find 1 stripped room info" - ); - assert!(store - .get_account_data_event(GlobalAccountDataEventType::PushRules) - .await? - .is_some()); - - assert!(store - .get_state_event(room_id, StateEventType::RoomName, "") - .await? - .is_some()); - assert_eq!( - store.get_state_events(room_id, StateEventType::RoomTopic).await?.len(), - 1, - "Expected to find 1 room topic" - ); - assert!(store.get_profile(room_id, user_id).await?.is_some()); - assert!(store.get_member_event(room_id, user_id).await?.is_some()); - assert_eq!( - store.get_user_ids(room_id).await?.len(), - 2, - "Expected to find 2 members for room" - ); - assert_eq!( - store.get_invited_user_ids(room_id).await?.len(), - 1, - "Expected to find 1 invited user ids" - ); - assert_eq!( - store.get_joined_user_ids(room_id).await?.len(), - 1, - "Expected to find 1 joined user ids" - ); - assert_eq!( - store.get_users_with_display_name(room_id, "example").await?.len(), - 2, - "Expected to find 2 display names for room" - ); - assert!(store - .get_room_account_data_event(room_id, RoomAccountDataEventType::Tag) - .await? - .is_some()); - assert!(store - .get_user_room_receipt_event(room_id, ReceiptType::Read, user_id) - .await? - .is_some()); - assert_eq!( - store - .get_event_room_receipt_events( - room_id, - ReceiptType::Read, - first_receipt_event_id() - ) - .await? - .len(), - 1, - "Expected to find 1 read receipt" - ); - Ok(()) - } - - #[async_test] - async fn test_member_saving() { - let store = get_store().await.unwrap(); - let room_id = room_id!("!test_member_saving:localhost"); - let user_id = user_id(); - - assert!(store.get_member_event(room_id, user_id).await.unwrap().is_none()); - let mut changes = StateChanges::default(); - changes - .members - .entry(room_id.to_owned()) - .or_default() - .insert(user_id.to_owned(), membership_event()); - - store.save_changes(&changes).await.unwrap(); - assert!(store.get_member_event(room_id, user_id).await.unwrap().is_some()); - - let members = store.get_user_ids(room_id).await.unwrap(); - assert!(!members.is_empty(), "We expected to find members for the room") - } - - #[async_test] - async fn test_filter_saving() { - let store = get_store().await.unwrap(); - let test_name = "filter_name"; - let filter_id = "filter_id_1234"; - assert_eq!(store.get_filter(test_name).await.unwrap(), None); - store.save_filter(test_name, filter_id).await.unwrap(); - assert_eq!(store.get_filter(test_name).await.unwrap(), Some(filter_id.to_owned())); - } - - #[async_test] - async fn test_sync_token_saving() { - let mut changes = StateChanges::default(); - let store = get_store().await.unwrap(); - let sync_token = "t392-516_47314_0_7_1".to_owned(); - - changes.sync_token = Some(sync_token.clone()); - assert_eq!(store.get_sync_token().await.unwrap(), None); - store.save_changes(&changes).await.unwrap(); - assert_eq!(store.get_sync_token().await.unwrap(), Some(sync_token)); - } - - #[async_test] - async fn test_stripped_member_saving() { - let store = get_store().await.unwrap(); - let room_id = room_id!("!test_stripped_member_saving:localhost"); - let user_id = user_id(); - - assert!(store.get_member_event(room_id, user_id).await.unwrap().is_none()); - let mut changes = StateChanges::default(); - changes - .stripped_members - .entry(room_id.to_owned()) - .or_default() - .insert(user_id.to_owned(), stripped_membership_event()); - - store.save_changes(&changes).await.unwrap(); - assert!(store.get_member_event(room_id, user_id).await.unwrap().is_some()); - - let members = store.get_user_ids(room_id).await.unwrap(); - assert!(!members.is_empty(), "We expected to find members for the room") - } - - #[async_test] - async fn test_power_level_saving() { - let store = get_store().await.unwrap(); - let room_id = room_id!("!test_power_level_saving:localhost"); - - let raw_event = power_level_event(); - let event = raw_event.deserialize().unwrap(); - - assert!(store - .get_state_event(room_id, StateEventType::RoomPowerLevels, "") - .await - .unwrap() - .is_none()); - let mut changes = StateChanges::default(); - changes.add_state_event(room_id, event, raw_event); - - store.save_changes(&changes).await.unwrap(); - assert!(store - .get_state_event(room_id, StateEventType::RoomPowerLevels, "") - .await - .unwrap() - .is_some()); - } - - #[async_test] - async fn test_receipts_saving() { - let store = get_store().await.expect("creating store failed"); - - let room_id = room_id!("!test_receipts_saving:localhost"); - - let first_event_id = event_id!("$1435641916114394fHBLK:matrix.org"); - let second_event_id = event_id!("$fHBLK1435641916114394:matrix.org"); - - let first_receipt_event = serde_json::from_value(json!({ - first_event_id: { - "m.read": { - user_id(): { - "ts": 1436451550453u64 - } - } - } - })) - .expect("json creation failed"); - - let second_receipt_event = serde_json::from_value(json!({ - second_event_id: { - "m.read": { - user_id(): { - "ts": 1436451551453u64 - } - } - } - })) - .expect("json creation failed"); - - assert!(store - .get_user_room_receipt_event(room_id, ReceiptType::Read, user_id()) - .await - .expect("failed to read user room receipt") - .is_none()); - assert!(store - .get_event_room_receipt_events(room_id, ReceiptType::Read, &first_event_id) - .await - .expect("failed to read user room receipt for 1") - .is_empty()); - assert!(store - .get_event_room_receipt_events(room_id, ReceiptType::Read, &second_event_id) - .await - .expect("failed to read user room receipt for 2") - .is_empty()); - - let mut changes = StateChanges::default(); - changes.add_receipts(room_id, first_receipt_event); - - store.save_changes(&changes).await.expect("writing changes fauked"); - assert!(store - .get_user_room_receipt_event(room_id, ReceiptType::Read, user_id()) - .await - .expect("failed to read user room receipt after save") - .is_some()); - assert_eq!( - store - .get_event_room_receipt_events(room_id, ReceiptType::Read, &first_event_id) - .await - .expect("failed to read user room receipt for 1 after save") - .len(), - 1, - "Found a wrong number of receipts for 1 after save" - ); - assert!(store - .get_event_room_receipt_events(room_id, ReceiptType::Read, &second_event_id) - .await - .expect("failed to read user room receipt for 2 after save") - .is_empty()); - - let mut changes = StateChanges::default(); - changes.add_receipts(room_id, second_receipt_event); - - store.save_changes(&changes).await.expect("Saving works"); - assert!(store - .get_user_room_receipt_event(room_id, ReceiptType::Read, user_id()) - .await - .expect("Getting user room receipts failed") - .is_some()); - assert!(store - .get_event_room_receipt_events(room_id, ReceiptType::Read, &first_event_id) - .await - .expect("Getting event room receipt events for first event failed") - .is_empty()); - assert_eq!( - store - .get_event_room_receipt_events(room_id, ReceiptType::Read, &second_event_id) - .await - .expect("Getting event room receipt events for second event failed") - .len(), - 1, - "Found a wrong number of receipts for second event after save" - ); - } + use $crate::media::{MediaFormat, MediaRequest, MediaThumbnailSize}; #[async_test] async fn test_media_content() { @@ -655,147 +116,699 @@ macro_rules! statestore_integration_tests { "thumbnail wasn't removed" ); } + } + }; + () => { + mod statestore_integration_tests { + $crate::statestore_integration_tests!(@inner); + } + }; + (@inner) => { + use std::{ + collections::{BTreeMap, BTreeSet}, + sync::Arc, + }; - #[async_test] - async fn test_custom_storage() -> StoreResult<()> { - let key = "my_key"; - let value = &[0, 1, 2, 3]; - let store = get_store().await?; + use matrix_sdk_test::{async_test, test_json}; + use ruma::{ + event_id, + events::{ + presence::PresenceEvent, + receipt::ReceiptType, + room::{ + member::{ + MembershipState, OriginalSyncRoomMemberEvent, RoomMemberEventContent, + RoomMemberUnsigned, StrippedRoomMemberEvent, SyncRoomMemberEvent, + }, + power_levels::RoomPowerLevelsEventContent, + topic::{RoomTopicEventContent, OriginalRoomTopicEvent, RedactedRoomTopicEvent}, + }, + AnyEphemeralRoomEventContent, AnyGlobalAccountDataEvent, + AnyRoomAccountDataEvent, AnyStrippedStateEvent, AnySyncEphemeralRoomEvent, + AnySyncStateEvent, GlobalAccountDataEventType, RoomAccountDataEventType, + StateEventType, + }, + room_id, + serde::Raw, + user_id, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, RoomId, UserId, + }; + use serde_json::{json, Value as JsonValue}; - store.set_custom_value(key.as_bytes(), value.to_vec()).await?; + use $crate::{ + store::{Result as StoreResult, StateChanges, StateStore, StateStoreExt}, + RoomInfo, RoomType, + }; - let read = store.get_custom_value(key.as_bytes()).await?; + use super::get_store; - assert_eq!(Some(value.as_ref()), read.as_deref()); + fn user_id() -> &'static UserId { + user_id!("@example:localhost") + } + pub(crate) fn invited_user_id() -> &'static UserId { + user_id!("@invited:localhost") + } - Ok(()) + pub(crate) fn room_id() -> &'static RoomId { + room_id!("!test:localhost") + } + + pub(crate) fn stripped_room_id() -> &'static RoomId { + room_id!("!stripped:localhost") + } + + pub(crate) fn first_receipt_event_id() -> &'static EventId { + event_id!("$example") + } + + /// Populate the given `StateStore`. + pub async fn populate_store(store: Arc) -> StoreResult<()> { + let mut changes = StateChanges::default(); + + let user_id = user_id(); + let invited_user_id = invited_user_id(); + let room_id = room_id(); + let stripped_room_id = stripped_room_id(); + + changes.sync_token = Some("t392-516_47314_0_7_1_1_1_11444_1".to_owned()); + + let presence_json: &JsonValue = &test_json::PRESENCE; + let presence_raw = + serde_json::from_value::>(presence_json.clone()).unwrap(); + let presence_event = presence_raw.deserialize().unwrap(); + changes.add_presence_event(presence_event, presence_raw); + + let pushrules_json: &JsonValue = &test_json::PUSH_RULES; + let pushrules_raw = serde_json::from_value::>( + pushrules_json.clone(), + ) + .unwrap(); + let pushrules_event = pushrules_raw.deserialize().unwrap(); + changes.add_account_data(pushrules_event, pushrules_raw); + + let mut room = RoomInfo::new(room_id, RoomType::Joined); + room.mark_as_left(); + + let tag_json: &JsonValue = &test_json::TAG; + let tag_raw = + serde_json::from_value::>(tag_json.clone()) + .unwrap(); + let tag_event = tag_raw.deserialize().unwrap(); + changes.add_room_account_data(room_id, tag_event, tag_raw); + + let name_json: &JsonValue = &test_json::NAME; + let name_raw = + serde_json::from_value::>(name_json.clone()).unwrap(); + let name_event = name_raw.deserialize().unwrap(); + room.handle_state_event(&name_event); + changes.add_state_event(room_id, name_event, name_raw); + + let topic_json: &JsonValue = &test_json::TOPIC; + let topic_raw = + serde_json::from_value::>(topic_json.clone()).expect("can create sync-state-event for topic"); + let topic_event = topic_raw.deserialize().expect("can deserialize raw topic"); + room.handle_state_event(&topic_event); + changes.add_state_event(room_id, topic_event, topic_raw); + + let mut room_ambiguity_map = BTreeMap::new(); + let mut room_profiles = BTreeMap::new(); + let mut room_members = BTreeMap::new(); + + let member_json: &JsonValue = &test_json::MEMBER; + let member_event: SyncRoomMemberEvent = + serde_json::from_value(member_json.clone()).unwrap(); + let displayname = + member_event.as_original().unwrap().content.displayname.clone().unwrap(); + room_ambiguity_map + .insert(displayname.clone(), BTreeSet::from([user_id.to_owned()])); + room_profiles.insert(user_id.to_owned(), (&member_event).into()); + room_members.insert(user_id.to_owned(), member_event); + + let member_state_raw = + serde_json::from_value::>(member_json.clone()).unwrap(); + let member_state_event = member_state_raw.deserialize().unwrap(); + changes.add_state_event(room_id, member_state_event, member_state_raw); + + let invited_member_json: &JsonValue = &test_json::MEMBER_INVITE; + // FIXME: Should be stripped room member event + let invited_member_event: SyncRoomMemberEvent = + serde_json::from_value(invited_member_json.clone()).unwrap(); + room_ambiguity_map + .entry(displayname) + .or_default() + .insert(invited_user_id.to_owned()); + room_profiles.insert(invited_user_id.to_owned(), (&invited_member_event).into()); + room_members.insert(invited_user_id.to_owned(), invited_member_event); + + let invited_member_state_raw = + serde_json::from_value::>(invited_member_json.clone()) + .unwrap(); + let invited_member_state_event = invited_member_state_raw.deserialize().unwrap(); + changes.add_state_event( + room_id, + invited_member_state_event, + invited_member_state_raw, + ); + + let receipt_json: &JsonValue = &test_json::READ_RECEIPT; + let receipt_event = + serde_json::from_value::(receipt_json.clone()) + .unwrap(); + let receipt_content = match receipt_event.content() { + AnyEphemeralRoomEventContent::Receipt(content) => content, + _ => panic!(), + }; + changes.add_receipts(room_id, receipt_content); + + changes.ambiguity_maps.insert(room_id.to_owned(), room_ambiguity_map); + changes.profiles.insert(room_id.to_owned(), room_profiles); + changes.members.insert(room_id.to_owned(), room_members); + changes.add_room(room); + + let mut stripped_room = RoomInfo::new(stripped_room_id, RoomType::Invited); + + let stripped_name_json: &JsonValue = &test_json::NAME_STRIPPED; + let stripped_name_raw = serde_json::from_value::>( + stripped_name_json.clone(), + ) + .unwrap(); + let stripped_name_event = stripped_name_raw.deserialize().unwrap(); + stripped_room.handle_stripped_state_event(&stripped_name_event); + changes.stripped_state.insert( + stripped_room_id.to_owned(), + BTreeMap::from([( + stripped_name_event.event_type(), + BTreeMap::from([( + stripped_name_event.state_key().to_owned(), + stripped_name_raw.clone(), + )]), + )]), + ); + + changes.add_stripped_room(stripped_room); + + let stripped_member_json: &JsonValue = &test_json::MEMBER_STRIPPED; + let stripped_member_event = + serde_json::from_value::(stripped_member_json.clone()) + .unwrap(); + changes.add_stripped_member(stripped_room_id, stripped_member_event); + + store.save_changes(&changes).await?; + Ok(()) + } + + fn power_level_event() -> Raw { + let content = RoomPowerLevelsEventContent::default(); + + let event = json!({ + "event_id": "$h29iv0s8:example.com", + "content": content, + "sender": user_id(), + "type": "m.room.power_levels", + "origin_server_ts": 0u64, + "state_key": "", + }); + + serde_json::from_value(event).unwrap() + } + + fn stripped_membership_event() -> StrippedRoomMemberEvent { + custom_stripped_membership_event(user_id()) } - #[async_test] - async fn test_persist_invited_room() -> StoreResult<()> { - let inner_store = get_store().await?; - let store = Arc::new(inner_store); - populate_store(store.clone()).await?; - - assert_eq!(store.get_stripped_room_infos().await?.len(), 1); - - Ok(()) + fn custom_stripped_membership_event(user_id: &UserId) -> StrippedRoomMemberEvent { + StrippedRoomMemberEvent { + content: RoomMemberEventContent::new(MembershipState::Join), + sender: user_id.to_owned(), + state_key: user_id.to_owned(), } + } - #[async_test] - async fn test_stripped_non_stripped() -> StoreResult<()> { - let store = get_store().await.unwrap(); - let room_id = room_id!("!test_stripped_non_stripped:localhost"); - let user_id = user_id(); + fn membership_event() -> SyncRoomMemberEvent { + custom_membership_event(user_id(), event_id!("$h29iv0s8:example.com").to_owned()) + } - assert!(store.get_member_event(room_id, user_id).await.unwrap().is_none()); - assert_eq!(store.get_room_infos().await.unwrap().len(), 0); - assert_eq!(store.get_stripped_room_infos().await.unwrap().len(), 0); + fn custom_membership_event( + user_id: &UserId, + event_id: OwnedEventId, + ) -> SyncRoomMemberEvent { + SyncRoomMemberEvent::Original(OriginalSyncRoomMemberEvent { + event_id, + content: RoomMemberEventContent::new(MembershipState::Join), + sender: user_id.to_owned(), + origin_server_ts: MilliSecondsSinceUnixEpoch(198u32.into()), + state_key: user_id.to_owned(), + unsigned: RoomMemberUnsigned::default(), + }) + } - let mut changes = StateChanges::default(); - changes - .members - .entry(room_id.to_owned()) - .or_default() - .insert(user_id.to_owned(), membership_event()); - changes.add_room(RoomInfo::new(room_id, RoomType::Left)); - store.save_changes(&changes).await.unwrap(); + #[async_test] + async fn test_topic_redaction() -> StoreResult<()> { + let room_id = room_id(); + let inner_store = get_store().await?; - assert!(matches!( - store.get_member_event(room_id, user_id).await.unwrap(), - Some($crate::deserialized_responses::MemberEvent::Sync(_)) - )); - assert_eq!(store.get_room_infos().await.unwrap().len(), 1); - assert_eq!(store.get_stripped_room_infos().await.unwrap().len(), 0); + let store = Arc::new(inner_store); + populate_store(store.clone()).await?; - let members = store.get_user_ids(room_id).await.unwrap(); - assert_eq!(members, vec![user_id.to_owned()]); - - let mut changes = StateChanges::default(); - changes.add_stripped_member(room_id, custom_stripped_membership_event(user_id)); - changes.add_stripped_room(RoomInfo::new(room_id, RoomType::Invited)); - store.save_changes(&changes).await.unwrap(); - - assert!(matches!( - store.get_member_event(room_id, user_id).await.unwrap(), - Some($crate::deserialized_responses::MemberEvent::Stripped(_)) - )); - assert_eq!(store.get_room_infos().await.unwrap().len(), 0); - assert_eq!(store.get_stripped_room_infos().await.unwrap().len(), 1); - - let members = store.get_user_ids(room_id).await.unwrap(); - assert_eq!(members, vec![user_id.to_owned()]); - - Ok(()) - } - - #[async_test] - async fn test_room_removal() -> StoreResult<()> { - let room_id = room_id(); - let user_id = user_id(); - let inner_store = get_store().await?; - let stripped_room_id = stripped_room_id(); - - let store = Arc::new(inner_store); - populate_store(store.clone()).await?; - - store.remove_room(room_id).await?; - - assert!(store.get_room_infos().await?.is_empty(), "room is still there"); - assert_eq!(store.get_stripped_room_infos().await?.len(), 1); - - assert!(store - .get_state_event(room_id, StateEventType::RoomName, "") + assert!(store.get_sync_token().await?.is_some()); + assert_eq!( + store + .get_state_event_static::(room_id) .await? - .is_none()); - assert!( - store.get_state_events(room_id, StateEventType::RoomTopic).await?.is_empty(), - "still state events found" - ); - assert!(store.get_profile(room_id, user_id).await?.is_none()); - assert!(store.get_member_event(room_id, user_id).await?.is_none()); - assert!(store.get_user_ids(room_id).await?.is_empty(), "still user ids found"); - assert!( - store.get_invited_user_ids(room_id).await?.is_empty(), - "still invited user ids found" - ); - assert!( - store.get_joined_user_ids(room_id).await?.is_empty(), - "still joined users found" - ); - assert!( - store.get_users_with_display_name(room_id, "example").await?.is_empty(), - "still display names found" - ); - assert!(store - .get_room_account_data_event(room_id, RoomAccountDataEventType::Tag) - .await? - .is_none()); - assert!(store - .get_user_room_receipt_event(room_id, ReceiptType::Read, user_id) - .await? - .is_none()); - assert!( - store - .get_event_room_receipt_events( - room_id, - ReceiptType::Read, - first_receipt_event_id() - ) - .await? - .is_empty(), - "still event recepts in the store" - ); + .expect("room topic found before redaction") + .deserialize_as::() + .expect("can deserialize room topic before redaction") + .content + .topic, + "😀" + ); - store.remove_room(stripped_room_id).await?; + let mut changes = StateChanges::default(); - assert!(store.get_room_infos().await?.is_empty(), "still room info found"); - assert!( - store.get_stripped_room_infos().await?.is_empty(), - "still stripped room info found" - ); - Ok(()) + let redaction_json: &JsonValue = &test_json::TOPIC_REDACTION; + let redaction_evt = serde_json::from_value(redaction_json.clone()).expect("topic redaction event making works"); + + changes.add_redaction(room_id, redaction_evt); + store.save_changes(&changes).await?; + + match store + .get_state_event_static::(room_id) + .await? + .expect("room topic found before redaction") + .deserialize_as::() + { + Err(_) => { } // as expected + Ok(_) => panic!("Topic has not been redacted") } + + let _ = store + .get_state_event_static::(room_id) + .await? + .expect("room topic found after redaction") + .deserialize_as::() + .expect("can deserialize room topic after redaction"); + + Ok(()) + } + + #[async_test] + async fn test_populate_store() -> StoreResult<()> { + let room_id = room_id(); + let user_id = user_id(); + let inner_store = get_store().await?; + + let store = Arc::new(inner_store); + populate_store(store.clone()).await?; + + assert!(store.get_sync_token().await?.is_some()); + assert!(store.get_presence_event(user_id).await?.is_some()); + assert_eq!(store.get_room_infos().await?.len(), 1, "Expected to find 1 room info"); + assert_eq!( + store.get_stripped_room_infos().await?.len(), + 1, + "Expected to find 1 stripped room info" + ); + assert!(store + .get_account_data_event(GlobalAccountDataEventType::PushRules) + .await? + .is_some()); + + assert!(store + .get_state_event(room_id, StateEventType::RoomName, "") + .await? + .is_some()); + assert_eq!( + store.get_state_events(room_id, StateEventType::RoomTopic).await?.len(), + 1, + "Expected to find 1 room topic" + ); + assert!(store.get_profile(room_id, user_id).await?.is_some()); + assert!(store.get_member_event(room_id, user_id).await?.is_some()); + assert_eq!( + store.get_user_ids(room_id).await?.len(), + 2, + "Expected to find 2 members for room" + ); + assert_eq!( + store.get_invited_user_ids(room_id).await?.len(), + 1, + "Expected to find 1 invited user ids" + ); + assert_eq!( + store.get_joined_user_ids(room_id).await?.len(), + 1, + "Expected to find 1 joined user ids" + ); + assert_eq!( + store.get_users_with_display_name(room_id, "example").await?.len(), + 2, + "Expected to find 2 display names for room" + ); + assert!(store + .get_room_account_data_event(room_id, RoomAccountDataEventType::Tag) + .await? + .is_some()); + assert!(store + .get_user_room_receipt_event(room_id, ReceiptType::Read, user_id) + .await? + .is_some()); + assert_eq!( + store + .get_event_room_receipt_events( + room_id, + ReceiptType::Read, + first_receipt_event_id() + ) + .await? + .len(), + 1, + "Expected to find 1 read receipt" + ); + Ok(()) + } + + #[async_test] + async fn test_member_saving() { + let store = get_store().await.unwrap(); + let room_id = room_id!("!test_member_saving:localhost"); + let user_id = user_id(); + + assert!(store.get_member_event(room_id, user_id).await.unwrap().is_none()); + let mut changes = StateChanges::default(); + changes + .members + .entry(room_id.to_owned()) + .or_default() + .insert(user_id.to_owned(), membership_event()); + + store.save_changes(&changes).await.unwrap(); + assert!(store.get_member_event(room_id, user_id).await.unwrap().is_some()); + + let members = store.get_user_ids(room_id).await.unwrap(); + assert!(!members.is_empty(), "We expected to find members for the room") + } + + #[async_test] + async fn test_filter_saving() { + let store = get_store().await.unwrap(); + let test_name = "filter_name"; + let filter_id = "filter_id_1234"; + assert_eq!(store.get_filter(test_name).await.unwrap(), None); + store.save_filter(test_name, filter_id).await.unwrap(); + assert_eq!(store.get_filter(test_name).await.unwrap(), Some(filter_id.to_owned())); + } + + #[async_test] + async fn test_sync_token_saving() { + let mut changes = StateChanges::default(); + let store = get_store().await.unwrap(); + let sync_token = "t392-516_47314_0_7_1".to_owned(); + + changes.sync_token = Some(sync_token.clone()); + assert_eq!(store.get_sync_token().await.unwrap(), None); + store.save_changes(&changes).await.unwrap(); + assert_eq!(store.get_sync_token().await.unwrap(), Some(sync_token)); + } + + #[async_test] + async fn test_stripped_member_saving() { + let store = get_store().await.unwrap(); + let room_id = room_id!("!test_stripped_member_saving:localhost"); + let user_id = user_id(); + + assert!(store.get_member_event(room_id, user_id).await.unwrap().is_none()); + let mut changes = StateChanges::default(); + changes + .stripped_members + .entry(room_id.to_owned()) + .or_default() + .insert(user_id.to_owned(), stripped_membership_event()); + + store.save_changes(&changes).await.unwrap(); + assert!(store.get_member_event(room_id, user_id).await.unwrap().is_some()); + + let members = store.get_user_ids(room_id).await.unwrap(); + assert!(!members.is_empty(), "We expected to find members for the room") + } + + #[async_test] + async fn test_power_level_saving() { + let store = get_store().await.unwrap(); + let room_id = room_id!("!test_power_level_saving:localhost"); + + let raw_event = power_level_event(); + let event = raw_event.deserialize().unwrap(); + + assert!(store + .get_state_event(room_id, StateEventType::RoomPowerLevels, "") + .await + .unwrap() + .is_none()); + let mut changes = StateChanges::default(); + changes.add_state_event(room_id, event, raw_event); + + store.save_changes(&changes).await.unwrap(); + assert!(store + .get_state_event(room_id, StateEventType::RoomPowerLevels, "") + .await + .unwrap() + .is_some()); + } + + #[async_test] + async fn test_receipts_saving() { + let store = get_store().await.expect("creating store failed"); + + let room_id = room_id!("!test_receipts_saving:localhost"); + + let first_event_id = event_id!("$1435641916114394fHBLK:matrix.org"); + let second_event_id = event_id!("$fHBLK1435641916114394:matrix.org"); + + let first_receipt_event = serde_json::from_value(json!({ + first_event_id: { + "m.read": { + user_id(): { + "ts": 1436451550453u64 + } + } + } + })) + .expect("json creation failed"); + + let second_receipt_event = serde_json::from_value(json!({ + second_event_id: { + "m.read": { + user_id(): { + "ts": 1436451551453u64 + } + } + } + })) + .expect("json creation failed"); + + assert!(store + .get_user_room_receipt_event(room_id, ReceiptType::Read, user_id()) + .await + .expect("failed to read user room receipt") + .is_none()); + assert!(store + .get_event_room_receipt_events(room_id, ReceiptType::Read, &first_event_id) + .await + .expect("failed to read user room receipt for 1") + .is_empty()); + assert!(store + .get_event_room_receipt_events(room_id, ReceiptType::Read, &second_event_id) + .await + .expect("failed to read user room receipt for 2") + .is_empty()); + + let mut changes = StateChanges::default(); + changes.add_receipts(room_id, first_receipt_event); + + store.save_changes(&changes).await.expect("writing changes fauked"); + assert!(store + .get_user_room_receipt_event(room_id, ReceiptType::Read, user_id()) + .await + .expect("failed to read user room receipt after save") + .is_some()); + assert_eq!( + store + .get_event_room_receipt_events(room_id, ReceiptType::Read, &first_event_id) + .await + .expect("failed to read user room receipt for 1 after save") + .len(), + 1, + "Found a wrong number of receipts for 1 after save" + ); + assert!(store + .get_event_room_receipt_events(room_id, ReceiptType::Read, &second_event_id) + .await + .expect("failed to read user room receipt for 2 after save") + .is_empty()); + + let mut changes = StateChanges::default(); + changes.add_receipts(room_id, second_receipt_event); + + store.save_changes(&changes).await.expect("Saving works"); + assert!(store + .get_user_room_receipt_event(room_id, ReceiptType::Read, user_id()) + .await + .expect("Getting user room receipts failed") + .is_some()); + assert!(store + .get_event_room_receipt_events(room_id, ReceiptType::Read, &first_event_id) + .await + .expect("Getting event room receipt events for first event failed") + .is_empty()); + assert_eq!( + store + .get_event_room_receipt_events(room_id, ReceiptType::Read, &second_event_id) + .await + .expect("Getting event room receipt events for second event failed") + .len(), + 1, + "Found a wrong number of receipts for second event after save" + ); + } + + #[async_test] + async fn test_custom_storage() -> StoreResult<()> { + let key = "my_key"; + let value = &[0, 1, 2, 3]; + let store = get_store().await?; + + store.set_custom_value(key.as_bytes(), value.to_vec()).await?; + + let read = store.get_custom_value(key.as_bytes()).await?; + + assert_eq!(Some(value.as_ref()), read.as_deref()); + + Ok(()) + } + + #[async_test] + async fn test_persist_invited_room() -> StoreResult<()> { + let inner_store = get_store().await?; + let store = Arc::new(inner_store); + populate_store(store.clone()).await?; + + assert_eq!(store.get_stripped_room_infos().await?.len(), 1); + + Ok(()) + } + + #[async_test] + async fn test_stripped_non_stripped() -> StoreResult<()> { + let store = get_store().await.unwrap(); + let room_id = room_id!("!test_stripped_non_stripped:localhost"); + let user_id = user_id(); + + assert!(store.get_member_event(room_id, user_id).await.unwrap().is_none()); + assert_eq!(store.get_room_infos().await.unwrap().len(), 0); + assert_eq!(store.get_stripped_room_infos().await.unwrap().len(), 0); + + let mut changes = StateChanges::default(); + changes + .members + .entry(room_id.to_owned()) + .or_default() + .insert(user_id.to_owned(), membership_event()); + changes.add_room(RoomInfo::new(room_id, RoomType::Left)); + store.save_changes(&changes).await.unwrap(); + + assert!(matches!( + store.get_member_event(room_id, user_id).await.unwrap(), + Some($crate::deserialized_responses::MemberEvent::Sync(_)) + )); + assert_eq!(store.get_room_infos().await.unwrap().len(), 1); + assert_eq!(store.get_stripped_room_infos().await.unwrap().len(), 0); + + let members = store.get_user_ids(room_id).await.unwrap(); + assert_eq!(members, vec![user_id.to_owned()]); + + let mut changes = StateChanges::default(); + changes.add_stripped_member(room_id, custom_stripped_membership_event(user_id)); + changes.add_stripped_room(RoomInfo::new(room_id, RoomType::Invited)); + store.save_changes(&changes).await.unwrap(); + + assert!(matches!( + store.get_member_event(room_id, user_id).await.unwrap(), + Some($crate::deserialized_responses::MemberEvent::Stripped(_)) + )); + assert_eq!(store.get_room_infos().await.unwrap().len(), 0); + assert_eq!(store.get_stripped_room_infos().await.unwrap().len(), 1); + + let members = store.get_user_ids(room_id).await.unwrap(); + assert_eq!(members, vec![user_id.to_owned()]); + + Ok(()) + } + + #[async_test] + async fn test_room_removal() -> StoreResult<()> { + let room_id = room_id(); + let user_id = user_id(); + let inner_store = get_store().await?; + let stripped_room_id = stripped_room_id(); + + let store = Arc::new(inner_store); + populate_store(store.clone()).await?; + + store.remove_room(room_id).await?; + + assert!(store.get_room_infos().await?.is_empty(), "room is still there"); + assert_eq!(store.get_stripped_room_infos().await?.len(), 1); + + assert!(store + .get_state_event(room_id, StateEventType::RoomName, "") + .await? + .is_none()); + assert!( + store.get_state_events(room_id, StateEventType::RoomTopic).await?.is_empty(), + "still state events found" + ); + assert!(store.get_profile(room_id, user_id).await?.is_none()); + assert!(store.get_member_event(room_id, user_id).await?.is_none()); + assert!(store.get_user_ids(room_id).await?.is_empty(), "still user ids found"); + assert!( + store.get_invited_user_ids(room_id).await?.is_empty(), + "still invited user ids found" + ); + assert!( + store.get_joined_user_ids(room_id).await?.is_empty(), + "still joined users found" + ); + assert!( + store.get_users_with_display_name(room_id, "example").await?.is_empty(), + "still display names found" + ); + assert!(store + .get_room_account_data_event(room_id, RoomAccountDataEventType::Tag) + .await? + .is_none()); + assert!(store + .get_user_room_receipt_event(room_id, ReceiptType::Read, user_id) + .await? + .is_none()); + assert!( + store + .get_event_room_receipt_events( + room_id, + ReceiptType::Read, + first_receipt_event_id() + ) + .await? + .is_empty(), + "still event recepts in the store" + ); + + store.remove_room(stripped_room_id).await?; + + assert!(store.get_room_infos().await?.is_empty(), "still room info found"); + assert!( + store.get_stripped_room_infos().await?.is_empty(), + "still stripped room info found" + ); + Ok(()) } }; } diff --git a/crates/matrix-sdk-base/src/store/memory_store.rs b/crates/matrix-sdk-base/src/store/memory_store.rs index 4c242d75a..26461a13d 100644 --- a/crates/matrix-sdk-base/src/store/memory_store.rs +++ b/crates/matrix-sdk-base/src/store/memory_store.rs @@ -19,7 +19,6 @@ use std::{ use async_trait::async_trait; use dashmap::{DashMap, DashSet}; -use lru::LruCache; #[allow(unused_imports)] use matrix_sdk_common::{instant::Instant, locks::Mutex}; use ruma::{ @@ -38,11 +37,7 @@ use ruma::{ use tracing::{info, warn}; use super::{Result, RoomInfo, StateChanges, StateStore, StoreError}; -use crate::{ - deserialized_responses::MemberEvent, - media::{MediaRequest, UniqueKey}, - MinimalRoomMemberEvent, -}; +use crate::{deserialized_responses::MemberEvent, media::MediaRequest, MinimalRoomMemberEvent}; /// In-Memory, non-persistent implementation of the `StateStore` /// @@ -76,7 +71,6 @@ pub struct MemoryStore { room_event_receipts: Arc< DashMap>>>, >, - media: Arc>>>, custom: Arc, Vec>>, } @@ -110,6 +104,7 @@ impl MemoryStore { presence: Default::default(), room_user_receipts: Default::default(), room_event_receipts: Default::default(), + #[cfg(feature = "memory-media-cache")] media: Arc::new(Mutex::new(LruCache::new( 100.try_into().expect("100 is a non-zero usize"), ))), @@ -526,36 +521,17 @@ impl MemoryStore { Ok(self.custom.insert(key.to_vec(), value)) } - async fn add_media_content(&self, request: &MediaRequest, data: Vec) -> Result<()> { - self.media.lock().await.put(request.unique_key(), data); - + // The in-memory store doesn't cache media + async fn add_media_content(&self, _request: &MediaRequest, _data: Vec) -> Result<()> { Ok(()) } - - async fn get_media_content(&self, request: &MediaRequest) -> Result>> { - Ok(self.media.lock().await.get(&request.unique_key()).cloned()) + async fn get_media_content(&self, _request: &MediaRequest) -> Result>> { + Ok(None) } - - async fn remove_media_content(&self, request: &MediaRequest) -> Result<()> { - self.media.lock().await.pop(&request.unique_key()); - + async fn remove_media_content(&self, _request: &MediaRequest) -> Result<()> { Ok(()) } - - async fn remove_media_content_for_uri(&self, uri: &MxcUri) -> Result<()> { - let mut media_store = self.media.lock().await; - - let keys: Vec = media_store - .iter() - .filter_map( - |(key, _)| if key.starts_with(&uri.to_string()) { Some(key.clone()) } else { None }, - ) - .collect(); - - for key in keys { - media_store.pop(&key); - } - + async fn remove_media_content_for_uri(&self, _uri: &MxcUri) -> Result<()> { Ok(()) } diff --git a/crates/matrix-sdk-indexeddb/src/state_store.rs b/crates/matrix-sdk-indexeddb/src/state_store.rs index c5da59a13..443b5f1f0 100644 --- a/crates/matrix-sdk-indexeddb/src/state_store.rs +++ b/crates/matrix-sdk-indexeddb/src/state_store.rs @@ -1401,7 +1401,7 @@ mod tests { Ok(IndexeddbStateStore::builder().name(db_name).build().await?) } - statestore_integration_tests!(); + statestore_integration_tests!(with_media_tests); } #[cfg(all(test, target_arch = "wasm32"))] @@ -1420,7 +1420,7 @@ mod encrypted_tests { Ok(IndexeddbStateStore::builder().name(db_name).passphrase(passphrase).build().await?) } - statestore_integration_tests!(); + statestore_integration_tests!(with_media_tests); } #[cfg(all(test, target_arch = "wasm32"))] diff --git a/crates/matrix-sdk-sled/src/state_store.rs b/crates/matrix-sdk-sled/src/state_store.rs index 5f2cc970c..668728106 100644 --- a/crates/matrix-sdk-sled/src/state_store.rs +++ b/crates/matrix-sdk-sled/src/state_store.rs @@ -1508,7 +1508,7 @@ mod tests { SledStateStore::builder().build().map_err(Into::into) } - statestore_integration_tests!(); + statestore_integration_tests!(with_media_tests); } #[cfg(test)] @@ -1521,7 +1521,7 @@ mod encrypted_tests { SledStateStoreBuilder::build_encrypted().map_err(Into::into) } - statestore_integration_tests!(); + statestore_integration_tests!(with_media_tests); } #[cfg(test)] diff --git a/crates/matrix-sdk/tests/integration/client.rs b/crates/matrix-sdk/tests/integration/client.rs index 9538c112c..27f7fa5aa 100644 --- a/crates/matrix-sdk/tests/integration/client.rs +++ b/crates/matrix-sdk/tests/integration/client.rs @@ -506,12 +506,9 @@ async fn get_media_content() { Mock::given(method("GET")) .and(path("/_matrix/media/r0/download/localhost/textfile")) .respond_with(ResponseTemplate::new(200).set_body_string("Some very interesting text.")) - .expect(2) .mount(&server) .await; - client.media().get_media_content(&request, true).await.unwrap(); - client.media().get_media_content(&request, true).await.unwrap(); client.media().get_media_content(&request, false).await.unwrap(); } @@ -533,13 +530,11 @@ async fn get_media_file() { Mock::given(method("GET")) .and(path("/_matrix/media/r0/download/example%2Eorg/image")) .respond_with(ResponseTemplate::new(200).set_body_raw("binaryjpegdata", "image/jpeg")) - .expect(1) .named("get_file") .mount(&server) .await; - client.media().get_file(event_content.clone(), true).await.unwrap(); - client.media().get_file(event_content.clone(), true).await.unwrap(); + client.media().get_file(event_content.clone(), false).await.unwrap(); Mock::given(method("GET")) .and(path("/_matrix/media/r0/thumbnail/example%2Eorg/image")) @@ -556,7 +551,7 @@ async fn get_media_file() { .get_thumbnail( event_content, MediaThumbnailSize { method: Method::Scale, width: uint!(100), height: uint!(100) }, - true, + false, ) .await .unwrap();