Skip to main content

matrix_sdk_base/store/
integration_tests.rs

1//! Trait and macro of integration tests for StateStore implementations.
2
3use std::{
4    collections::{BTreeMap, BTreeSet, HashMap},
5    str::FromStr,
6};
7
8use assert_matches::assert_matches;
9use growable_bloom_filter::GrowableBloomBuilder;
10use matrix_sdk_common::ttl::TtlValue;
11use matrix_sdk_test::{TestResult, event_factory::EventFactory};
12use ruma::{
13    EventId, MilliSecondsSinceUnixEpoch, OwnedUserId, RoomId, TransactionId, UserId,
14    api::{
15        FeatureFlag, MatrixVersion,
16        client::{
17            discovery::discover_homeserver::HomeserverInfo,
18            rtc::{LiveKitRtcTransport, RtcTransport},
19        },
20    },
21    event_id,
22    events::{
23        AnyGlobalAccountDataEvent, AnyMessageLikeEventContent, AnyRoomAccountDataEvent,
24        AnyStrippedStateEvent, AnySyncStateEvent, GlobalAccountDataEventType,
25        RoomAccountDataEventType, StateEventType, SyncStateEvent,
26        presence::PresenceEvent,
27        receipt::{ReceiptThread, ReceiptType},
28        room::{
29            member::{
30                MembershipState, RoomMemberEventContent, StrippedRoomMemberEvent,
31                SyncRoomMemberEvent,
32            },
33            message::RoomMessageEventContent,
34            power_levels::RoomPowerLevelsEventContent,
35            redaction::SyncRoomRedactionEvent,
36            topic::RoomTopicEventContent,
37        },
38        tag::{TagInfo, TagName, Tags, UserTagName},
39    },
40    mxc_uri, owned_event_id, owned_mxc_uri,
41    presence::PresenceState,
42    profile::{ProfileFieldName, UserProfileChanges, UserProfileUpdate},
43    push::Ruleset,
44    room_id,
45    room_version_rules::AuthorizationRules,
46    serde::Raw,
47    uint, user_id,
48};
49use serde_json::json;
50use strass::assert_let;
51
52#[cfg(feature = "unstable-msc4354")]
53use super::QueuedRequestKind;
54use super::{
55    DependentQueuedRequestKind, DisplayName, DynStateStore, RoomLoadSettings,
56    SupportedVersionsResponse, WellKnownResponse, send_queue::SentRequestKey,
57};
58use crate::{
59    RoomInfo, RoomMemberships, RoomState, StateChanges, StateStoreDataKey, StateStoreDataValue,
60    deserialized_responses::MemberEvent,
61    store::{
62        ChildTransactionId, QueueWedgeError, SerializableEventContent, StateStoreExt,
63        StoredThreadSubscription, ThreadSubscriptionStatus,
64    },
65    utils::RawStateEventWithKeys,
66};
67
68/// `StateStore` integration tests.
69///
70/// This trait is not meant to be used directly, but will be used with the
71/// `statestore_integration_tests!` macro.
72#[allow(async_fn_in_trait)]
73pub trait StateStoreIntegrationTests {
74    /// Populate the given `StateStore`.
75    async fn populate(&self) -> TestResult;
76    /// Test room topic redaction.
77    async fn test_topic_redaction(&self) -> TestResult;
78    /// Test populating the store.
79    async fn test_populate_store(&self) -> TestResult;
80    /// Test room member saving.
81    async fn test_member_saving(&self) -> TestResult;
82    /// Test filter saving.
83    async fn test_filter_saving(&self) -> TestResult;
84    /// Test saving a user avatar URL.
85    async fn test_user_avatar_url_saving(&self) -> TestResult;
86    /// Test sync token saving.
87    async fn test_sync_token_saving(&self) -> TestResult;
88    /// Test UtdHookManagerData saving.
89    async fn test_utd_hook_manager_data_saving(&self) -> TestResult;
90    /// Test the saving of the OneTimeKeyAlreadyUploaded key/value data type.
91    async fn test_one_time_key_already_uploaded_data_saving(&self) -> TestResult;
92    /// Test stripped room member saving.
93    async fn test_stripped_member_saving(&self) -> TestResult;
94    /// Test room power levels saving.
95    async fn test_power_level_saving(&self) -> TestResult;
96    /// Test user receipts saving.
97    async fn test_receipts_saving(&self) -> TestResult;
98    /// Test custom storage.
99    async fn test_custom_storage(&self) -> TestResult;
100    /// Test stripped and non-stripped room member saving.
101    async fn test_stripped_non_stripped(&self) -> TestResult;
102    /// Test that a stripped room keeps its stripped state across saves.
103    async fn test_stripped_state_is_kept_across_saves(&self) -> TestResult;
104    /// Test that a room info only save doesn't drop the room's data.
105    async fn test_room_info_only_save_keeps_room_data(&self) -> TestResult;
106    /// Test room removal.
107    async fn test_room_removal(&self) -> TestResult;
108    /// Test profile removal.
109    async fn test_profile_removal(&self) -> TestResult;
110    /// Test presence saving.
111    async fn test_presence_saving(&self) -> TestResult;
112    /// Test display names saving.
113    async fn test_display_names_saving(&self) -> TestResult;
114    /// Test operations with the send queue.
115    async fn test_send_queue(&self) -> TestResult;
116    /// Test priority of operations with the send queue.
117    async fn test_send_queue_priority(&self) -> TestResult;
118    /// Test operations related to send queue dependents.
119    async fn test_send_queue_dependents(&self) -> TestResult;
120    /// Test that the sticky duration of a queued event survives a round-trip.
121    async fn test_send_queue_sticky_events(&self) -> TestResult;
122    /// Test an update to a send queue dependent request.
123    async fn test_update_send_queue_dependent(&self) -> TestResult;
124    /// Test saving/restoring the supported versions of the server.
125    async fn test_supported_versions_saving(&self) -> TestResult;
126    /// Test saving/restoring the well-known info of the server.
127    async fn test_well_known_saving(&self) -> TestResult;
128    /// Test fetching room infos based on [`RoomLoadSettings`].
129    async fn test_get_room_infos(&self) -> TestResult;
130    /// Test loading thread subscriptions.
131    async fn test_thread_subscriptions(&self) -> TestResult;
132    /// Test thread subscriptions bulk upsert, including bumpstamp semantics.
133    async fn test_thread_subscriptions_bulk_upsert(&self) -> TestResult;
134    /// Test global profiles bulk saving and merging.
135    async fn test_global_profiles_saving(&self) -> TestResult;
136    /// Test loading global profiles for several users at once.
137    async fn test_global_profiles_bulk_loading(&self) -> TestResult;
138    /// Test missing global profiles inc tracking unavailable ones.
139    async fn test_missing_global_profiles(&self) -> TestResult;
140}
141
142impl StateStoreIntegrationTests for DynStateStore {
143    async fn populate(&self) -> TestResult {
144        let mut changes = StateChanges::default();
145
146        let user_id = user_id();
147        let invited_user_id = invited_user_id();
148        let room_id = room_id();
149        let stripped_room_id = stripped_room_id();
150
151        changes.sync_token = Some("t392-516_47314_0_7_1_1_1_11444_1".to_owned());
152
153        let f = EventFactory::new().sender(user_id);
154        let presence_raw: Raw<PresenceEvent> = f
155            .presence(PresenceState::Online)
156            .avatar_url(mxc_uri!("mxc://localhost/wefuiwegh8742w"))
157            .currently_active(false)
158            .last_active_ago(1)
159            .status_msg("Making cupcakes")
160            .into();
161        let presence_event = presence_raw.deserialize()?;
162        changes.add_presence_event(presence_event, presence_raw);
163
164        let f = EventFactory::new().sender(user_id);
165        let pushrules_raw: Raw<AnyGlobalAccountDataEvent> =
166            f.push_rules(Ruleset::server_default(user_id)).into();
167        let pushrules_event = pushrules_raw.deserialize()?;
168        changes.account_data.insert(pushrules_event.event_type(), pushrules_raw);
169
170        let mut room = RoomInfo::new(room_id, RoomState::Joined);
171        room.mark_as_left();
172
173        let f = EventFactory::new().sender(user_id).room(room_id);
174        let mut tags = Tags::new();
175        tags.insert(TagName::Favorite, TagInfo::new());
176        tags.insert(TagName::User(UserTagName::from_str("u.work").unwrap()), TagInfo::new());
177        let tag_raw: Raw<AnyRoomAccountDataEvent> = f.tag(tags).into();
178        let tag_event = tag_raw.deserialize()?;
179        changes.add_room_account_data(room_id, tag_event, tag_raw);
180
181        let f = EventFactory::new().sender(user_id).room(room_id);
182        let name_raw: Raw<AnySyncStateEvent> = f.room_name("room name").into();
183        let name_event = name_raw.deserialize()?;
184        room.handle_state_event(
185            &mut RawStateEventWithKeys::try_from_raw_state_event(name_raw.clone())
186                .expect("generated state event should be valid"),
187        );
188        changes.add_state_event(room_id, name_event, name_raw);
189
190        let f = EventFactory::new().sender(user_id);
191        let receipt_content = f
192            .room(room_id)
193            .read_receipts()
194            .add(event_id!("$example"), user_id, ReceiptType::Read, ReceiptThread::Unthreaded)
195            .into_content();
196        changes.add_receipts(room_id, receipt_content);
197
198        let topic_event_id = topic_event_id();
199        let topic_raw: Raw<AnySyncStateEvent> = EventFactory::new()
200            .room(room_id)
201            .sender(user_id)
202            .room_topic("😀")
203            .event_id(topic_event_id)
204            .prev_content(RoomTopicEventContent::new("test".to_owned()))
205            .into_raw_sync_state();
206        let topic_event = topic_raw.deserialize()?;
207        room.handle_state_event(
208            &mut RawStateEventWithKeys::try_from_raw_state_event(topic_raw.clone())
209                .expect("generated state event should be valid"),
210        );
211        changes.add_state_event(room_id, topic_event, topic_raw);
212
213        let mut room_ambiguity_map = HashMap::new();
214        let mut room_profiles = BTreeMap::new();
215
216        let f = EventFactory::new().sender(user_id).room(room_id);
217        let member_raw: Raw<SyncRoomMemberEvent> =
218            f.member(user_id).display_name("example").previous(MembershipState::Invite).into();
219        let member_event: SyncRoomMemberEvent = member_raw.deserialize()?;
220        let displayname = DisplayName::new(
221            member_event.as_original().unwrap().content.displayname.as_ref().unwrap(),
222        );
223        room_ambiguity_map.insert(displayname.clone(), BTreeSet::from([user_id.to_owned()]));
224        room_profiles.insert(user_id.to_owned(), (&member_event).into());
225
226        let member_raw: Raw<AnySyncStateEvent> = member_raw.cast_unchecked();
227        let member_state_event = member_raw.deserialize()?;
228        changes.add_state_event(room_id, member_state_event, member_raw);
229
230        let f = EventFactory::new().sender(user_id).room(room_id);
231        let invited_member_raw: Raw<SyncRoomMemberEvent> = f
232            .member(invited_user_id)
233            .invited(invited_user_id)
234            .display_name("example")
235            .avatar_url(mxc_uri!("mxc://localhost/SEsfnsuifSDFSSEF"))
236            .reason("Looking for support")
237            .into();
238        // FIXME: Should be stripped room member event
239        let invited_member_event: SyncRoomMemberEvent = invited_member_raw.deserialize()?;
240        room_ambiguity_map.entry(displayname).or_default().insert(invited_user_id.to_owned());
241        room_profiles.insert(invited_user_id.to_owned(), (&invited_member_event).into());
242
243        let invited_member_raw: Raw<AnySyncStateEvent> = invited_member_raw.cast_unchecked();
244        let invited_member_state_event = invited_member_raw.deserialize()?;
245        changes.add_state_event(room_id, invited_member_state_event, invited_member_raw);
246
247        changes.ambiguity_maps.insert(room_id.to_owned(), room_ambiguity_map);
248        changes.profiles.insert(room_id.to_owned(), room_profiles);
249        changes.add_room(room);
250
251        let mut stripped_room = RoomInfo::new(stripped_room_id, RoomState::Invited);
252
253        let f = EventFactory::new().sender(user_id).room(stripped_room_id);
254        let stripped_name_raw: Raw<AnyStrippedStateEvent> = f.room_name("room name").into();
255        let mut stripped_name_event =
256            RawStateEventWithKeys::try_from_raw_state_event(stripped_name_raw).unwrap();
257        stripped_room.handle_stripped_state_event(&mut stripped_name_event);
258        changes.stripped_state.insert(
259            stripped_room_id.to_owned(),
260            BTreeMap::from([(
261                stripped_name_event.event_type,
262                BTreeMap::from([(stripped_name_event.state_key, stripped_name_event.raw)]),
263            )]),
264        );
265
266        changes.add_room(stripped_room);
267
268        let f = EventFactory::new().sender(user_id).room(stripped_room_id);
269        let stripped_member_raw: Raw<StrippedRoomMemberEvent> =
270            f.member(user_id).display_name("example").into();
271        changes.add_stripped_member(stripped_room_id, user_id, stripped_member_raw);
272
273        self.save_changes(&changes).await?;
274
275        Ok(())
276    }
277
278    async fn test_topic_redaction(&self) -> TestResult {
279        let room_id = room_id();
280        let f = EventFactory::new();
281        self.populate().await?;
282
283        assert!(self.get_kv_data(StateStoreDataKey::SyncToken).await?.is_some());
284        assert_eq!(
285            self.get_state_event_static::<RoomTopicEventContent>(room_id)
286                .await?
287                .expect("room topic found before redaction")
288                .deserialize()
289                .expect("can deserialize room topic before redaction")
290                .as_sync()
291                .expect("room topic is a sync state event")
292                .as_original()
293                .expect("room topic is not redacted yet")
294                .content
295                .topic,
296            "😀"
297        );
298
299        let mut changes = StateChanges::default();
300
301        let topic_event_id = topic_event_id();
302        let redaction_evt: Raw<SyncRoomRedactionEvent> =
303            f.room(room_id).sender(user_id()).redaction(topic_event_id).into_raw();
304
305        changes.add_redaction(room_id, topic_event_id, redaction_evt);
306        self.save_changes(&changes).await?;
307
308        let redacted_event = self
309            .get_state_event_static::<RoomTopicEventContent>(room_id)
310            .await?
311            .expect("room topic found after redaction")
312            .deserialize()
313            .expect("can deserialize room topic after redaction");
314
315        assert_matches!(redacted_event.as_sync(), Some(SyncStateEvent::Redacted(_)));
316
317        Ok(())
318    }
319
320    async fn test_populate_store(&self) -> TestResult {
321        let room_id = room_id();
322        let user_id = user_id();
323        let display_name = DisplayName::new("example");
324
325        self.populate().await?;
326
327        assert!(self.get_kv_data(StateStoreDataKey::SyncToken).await?.is_some());
328        assert!(self.get_presence_event(user_id).await?.is_some());
329        assert_eq!(
330            self.get_room_infos(&RoomLoadSettings::default()).await?.len(),
331            2,
332            "Expected to find 2 room infos"
333        );
334        assert!(
335            self.get_account_data_event(GlobalAccountDataEventType::PushRules).await?.is_some()
336        );
337
338        assert!(self.get_state_event(room_id, StateEventType::RoomName, "").await?.is_some());
339        assert_eq!(
340            self.get_state_events(room_id, StateEventType::RoomTopic).await?.len(),
341            1,
342            "Expected to find 1 room topic"
343        );
344        assert!(self.get_profile(room_id, user_id).await?.is_some());
345        assert!(self.get_member_event(room_id, user_id).await?.is_some());
346        assert_eq!(
347            self.get_user_ids(room_id, RoomMemberships::empty()).await?.len(),
348            2,
349            "Expected to find 2 members for room"
350        );
351        assert_eq!(
352            self.get_user_ids(room_id, RoomMemberships::INVITE).await?.len(),
353            1,
354            "Expected to find 1 invited user ids"
355        );
356        assert_eq!(
357            self.get_user_ids(room_id, RoomMemberships::JOIN).await?.len(),
358            1,
359            "Expected to find 1 joined user ids"
360        );
361        assert_eq!(
362            self.get_users_with_display_name(room_id, &display_name).await?.len(),
363            2,
364            "Expected to find 2 display names for room"
365        );
366        assert!(
367            self.get_room_account_data_event(room_id, RoomAccountDataEventType::Tag)
368                .await?
369                .is_some()
370        );
371        assert!(
372            self.get_user_room_receipt_event(
373                room_id,
374                ReceiptType::Read,
375                &ReceiptThread::Unthreaded,
376                user_id
377            )
378            .await?
379            .is_some()
380        );
381        assert_eq!(
382            self.get_event_room_receipt_events(
383                room_id,
384                ReceiptType::Read,
385                &ReceiptThread::Unthreaded,
386                first_receipt_event_id()
387            )
388            .await?
389            .len(),
390            1,
391            "Expected to find 1 read receipt"
392        );
393        Ok(())
394    }
395
396    async fn test_member_saving(&self) -> TestResult {
397        let room_id = room_id!("!test_member_saving:localhost");
398        let user_id = user_id();
399        let second_user_id = user_id!("@second:localhost");
400        let third_user_id = user_id!("@third:localhost");
401        let unknown_user_id = user_id!("@unknown:localhost");
402
403        // No event in store.
404        let mut user_ids = vec![user_id.to_owned()];
405        assert!(self.get_member_event(room_id, user_id).await?.is_none());
406        let member_events = self
407            .get_state_events_for_keys_static::<RoomMemberEventContent, _, _>(room_id, &user_ids)
408            .await;
409        assert!(member_events?.is_empty());
410        assert!(self.get_profile(room_id, user_id).await?.is_none());
411        let profiles = self.get_profiles(room_id, &user_ids).await;
412        assert!(profiles?.is_empty());
413
414        // One event in store.
415        let mut changes = StateChanges::default();
416        let raw_member_event = membership_event();
417        let profile = raw_member_event.deserialize()?.into();
418        changes
419            .state
420            .entry(room_id.to_owned())
421            .or_default()
422            .entry(StateEventType::RoomMember)
423            .or_default()
424            .insert(user_id.into(), raw_member_event.cast());
425        changes.profiles.entry(room_id.to_owned()).or_default().insert(user_id.to_owned(), profile);
426        self.save_changes(&changes).await?;
427
428        assert!(self.get_member_event(room_id, user_id).await?.is_some());
429        let member_events = self
430            .get_state_events_for_keys_static::<RoomMemberEventContent, _, _>(room_id, &user_ids)
431            .await;
432        assert_eq!(member_events?.len(), 1);
433        let members = self.get_user_ids(room_id, RoomMemberships::empty()).await?;
434        assert_eq!(members.len(), 1, "We expected to find members for the room");
435        assert!(self.get_profile(room_id, user_id).await?.is_some());
436        let profiles = self.get_profiles(room_id, &user_ids).await;
437        assert_eq!(profiles?.len(), 1);
438
439        // Several events in store.
440        let mut changes = StateChanges::default();
441        let changes_members = changes
442            .state
443            .entry(room_id.to_owned())
444            .or_default()
445            .entry(StateEventType::RoomMember)
446            .or_default();
447        let changes_profiles = changes.profiles.entry(room_id.to_owned()).or_default();
448        let raw_second_member_event =
449            custom_membership_event(second_user_id, event_id!("$second_member_event"));
450        let second_profile = raw_second_member_event.deserialize()?.into();
451        changes_members.insert(second_user_id.into(), raw_second_member_event.cast());
452        changes_profiles.insert(second_user_id.to_owned(), second_profile);
453        let raw_third_member_event =
454            custom_membership_event(third_user_id, event_id!("$third_member_event"));
455        let third_profile = raw_third_member_event.deserialize()?.into();
456        changes_members.insert(third_user_id.into(), raw_third_member_event.cast());
457        changes_profiles.insert(third_user_id.to_owned(), third_profile);
458        self.save_changes(&changes).await?;
459
460        user_ids.extend([second_user_id.to_owned(), third_user_id.to_owned()]);
461        assert!(self.get_member_event(room_id, second_user_id).await?.is_some());
462        assert!(self.get_member_event(room_id, third_user_id).await?.is_some());
463        let member_events = self
464            .get_state_events_for_keys_static::<RoomMemberEventContent, _, _>(room_id, &user_ids)
465            .await;
466        assert_eq!(member_events?.len(), 3);
467        let members = self.get_user_ids(room_id, RoomMemberships::empty()).await?;
468        assert_eq!(members.len(), 3, "We expected to find members for the room");
469        assert!(self.get_profile(room_id, second_user_id).await?.is_some());
470        assert!(self.get_profile(room_id, third_user_id).await?.is_some());
471        let profiles = self.get_profiles(room_id, &user_ids).await;
472        assert_eq!(profiles?.len(), 3);
473
474        // Several events in store with one unknown.
475        user_ids.push(unknown_user_id.to_owned());
476        let member_events = self
477            .get_state_events_for_keys_static::<RoomMemberEventContent, _, _>(room_id, &user_ids)
478            .await;
479        assert_eq!(member_events?.len(), 3);
480        let profiles = self.get_profiles(room_id, &user_ids).await;
481        assert_eq!(profiles?.len(), 3);
482
483        // Empty user IDs list.
484        let member_events = self
485            .get_state_events_for_keys_static::<RoomMemberEventContent, OwnedUserId, _>(
486                room_id,
487                &[],
488            )
489            .await;
490        assert!(member_events?.is_empty());
491        let profiles = self.get_profiles(room_id, &[]).await;
492        assert!(profiles?.is_empty());
493
494        Ok(())
495    }
496
497    async fn test_filter_saving(&self) -> TestResult {
498        let filter_name = "filter_name";
499        let filter_id = "filter_id_1234";
500
501        self.set_kv_data(
502            StateStoreDataKey::Filter(filter_name),
503            StateStoreDataValue::Filter(filter_id.to_owned()),
504        )
505        .await?;
506        assert_let!(
507            Ok(Some(StateStoreDataValue::Filter(stored_filter_id))) =
508                self.get_kv_data(StateStoreDataKey::Filter(filter_name)).await
509        );
510        assert_eq!(stored_filter_id, filter_id);
511
512        self.remove_kv_data(StateStoreDataKey::Filter(filter_name)).await?;
513        assert_matches!(self.get_kv_data(StateStoreDataKey::Filter(filter_name)).await, Ok(None));
514
515        Ok(())
516    }
517
518    async fn test_user_avatar_url_saving(&self) -> TestResult {
519        let user_id = user_id!("@alice:example.org");
520        let url = owned_mxc_uri!("mxc://example.org/poiuyt098");
521
522        self.set_kv_data(
523            StateStoreDataKey::UserAvatarUrl(user_id),
524            StateStoreDataValue::UserAvatarUrl(url.clone()),
525        )
526        .await?;
527
528        assert_let!(
529            Ok(Some(StateStoreDataValue::UserAvatarUrl(stored_url))) =
530                self.get_kv_data(StateStoreDataKey::UserAvatarUrl(user_id)).await
531        );
532        assert_eq!(stored_url, url);
533
534        self.remove_kv_data(StateStoreDataKey::UserAvatarUrl(user_id)).await?;
535        assert_matches!(
536            self.get_kv_data(StateStoreDataKey::UserAvatarUrl(user_id)).await,
537            Ok(None)
538        );
539
540        Ok(())
541    }
542
543    async fn test_supported_versions_saving(&self) -> TestResult {
544        let versions =
545            BTreeSet::from([MatrixVersion::V1_1, MatrixVersion::V1_2, MatrixVersion::V1_11]);
546        let supported_versions = SupportedVersionsResponse {
547            versions: versions.iter().map(|version| version.as_str().unwrap().to_owned()).collect(),
548            unstable_features: [("org.matrix.experimental".to_owned(), true)].into(),
549        };
550
551        self.set_kv_data(
552            StateStoreDataKey::SupportedVersions,
553            StateStoreDataValue::SupportedVersions(TtlValue::new(supported_versions.clone())),
554        )
555        .await?;
556
557        assert_let!(
558            Ok(Some(StateStoreDataValue::SupportedVersions(stored_supported_versions))) =
559                self.get_kv_data(StateStoreDataKey::SupportedVersions).await
560        );
561        let stored_supported_versions = stored_supported_versions.into_data();
562        assert_eq!(supported_versions, stored_supported_versions);
563
564        let stored_supported = stored_supported_versions.supported_versions();
565        assert_eq!(stored_supported.versions, versions);
566        assert_eq!(stored_supported.features.len(), 1);
567        assert!(stored_supported.features.contains(&FeatureFlag::from("org.matrix.experimental")));
568
569        self.remove_kv_data(StateStoreDataKey::SupportedVersions).await?;
570        assert_matches!(self.get_kv_data(StateStoreDataKey::SupportedVersions).await, Ok(None));
571
572        Ok(())
573    }
574
575    async fn test_well_known_saving(&self) -> TestResult {
576        let well_known = WellKnownResponse {
577            homeserver: HomeserverInfo::new("matrix.example.com".to_owned()),
578            identity_server: None,
579            tile_server: None,
580            rtc_foci: vec![RtcTransport::LiveKit(LiveKitRtcTransport::new(
581                "wss://livekit.example.com".to_owned(),
582            ))],
583        };
584
585        self.set_kv_data(
586            StateStoreDataKey::WellKnown,
587            StateStoreDataValue::WellKnown(TtlValue::new(Some(well_known.clone()))),
588        )
589        .await?;
590
591        assert_let!(
592            Ok(Some(StateStoreDataValue::WellKnown(stored_well_known))) =
593                self.get_kv_data(StateStoreDataKey::WellKnown).await
594        );
595        let stored_well_known = stored_well_known.into_data();
596        assert_eq!(stored_well_known, Some(well_known));
597
598        self.remove_kv_data(StateStoreDataKey::WellKnown).await?;
599        assert_matches!(self.get_kv_data(StateStoreDataKey::WellKnown).await, Ok(None));
600
601        self.set_kv_data(
602            StateStoreDataKey::WellKnown,
603            StateStoreDataValue::WellKnown(TtlValue::new(None)),
604        )
605        .await?;
606
607        assert_let!(
608            Ok(Some(StateStoreDataValue::WellKnown(stored_well_known))) =
609                self.get_kv_data(StateStoreDataKey::WellKnown).await
610        );
611        let stored_well_known = stored_well_known.into_data();
612        assert_eq!(stored_well_known, None);
613
614        Ok(())
615    }
616
617    async fn test_sync_token_saving(&self) -> TestResult {
618        let sync_token_1 = "t392-516_47314_0_7_1";
619        let sync_token_2 = "t392-516_47314_0_7_2";
620
621        assert_matches!(self.get_kv_data(StateStoreDataKey::SyncToken).await, Ok(None));
622
623        let changes =
624            StateChanges { sync_token: Some(sync_token_1.to_owned()), ..Default::default() };
625        self.save_changes(&changes).await?;
626        assert_let!(
627            Ok(Some(StateStoreDataValue::SyncToken(stored_sync_token))) =
628                self.get_kv_data(StateStoreDataKey::SyncToken).await
629        );
630        assert_eq!(stored_sync_token, sync_token_1);
631
632        self.set_kv_data(
633            StateStoreDataKey::SyncToken,
634            StateStoreDataValue::SyncToken(sync_token_2.to_owned()),
635        )
636        .await?;
637        assert_let!(
638            Ok(Some(StateStoreDataValue::SyncToken(stored_sync_token))) =
639                self.get_kv_data(StateStoreDataKey::SyncToken).await
640        );
641        assert_eq!(stored_sync_token, sync_token_2);
642
643        self.remove_kv_data(StateStoreDataKey::SyncToken).await?;
644        assert_matches!(self.get_kv_data(StateStoreDataKey::SyncToken).await, Ok(None));
645
646        Ok(())
647    }
648
649    async fn test_utd_hook_manager_data_saving(&self) -> TestResult {
650        // Before any data is written, the getter should return None.
651        assert!(
652            self.get_kv_data(StateStoreDataKey::UtdHookManagerData)
653                .await
654                .expect("Could not read data")
655                .is_none(),
656            "Store was not empty at start"
657        );
658
659        // Put some data in the store...
660        let data = GrowableBloomBuilder::new().build();
661        self.set_kv_data(
662            StateStoreDataKey::UtdHookManagerData,
663            StateStoreDataValue::UtdHookManagerData(data.clone()),
664        )
665        .await
666        .expect("Could not save data");
667
668        // ... and check it comes back.
669        let read_data = self
670            .get_kv_data(StateStoreDataKey::UtdHookManagerData)
671            .await
672            .expect("Could not read data")
673            .expect("no data found")
674            .into_utd_hook_manager_data()
675            .expect("not UtdHookManagerData");
676
677        assert_eq!(read_data, data);
678
679        Ok(())
680    }
681
682    async fn test_one_time_key_already_uploaded_data_saving(&self) -> TestResult {
683        // Before any data is written, the getter should return None.
684        assert!(
685            self.get_kv_data(StateStoreDataKey::OneTimeKeyAlreadyUploaded).await?.is_none(),
686            "Store was not empty at start"
687        );
688
689        self.set_kv_data(
690            StateStoreDataKey::OneTimeKeyAlreadyUploaded,
691            StateStoreDataValue::OneTimeKeyAlreadyUploaded,
692        )
693        .await?;
694
695        let data = self.get_kv_data(StateStoreDataKey::OneTimeKeyAlreadyUploaded).await?;
696        data.expect("The loaded data should be Some");
697
698        Ok(())
699    }
700
701    async fn test_stripped_member_saving(&self) -> TestResult {
702        let room_id = room_id!("!test_stripped_member_saving:localhost");
703        let user_id = user_id();
704        let second_user_id = user_id!("@second:localhost");
705        let third_user_id = user_id!("@third:localhost");
706        let unknown_user_id = user_id!("@unknown:localhost");
707
708        // No event in store.
709        assert!(self.get_member_event(room_id, user_id).await?.is_none());
710        let member_events = self
711            .get_state_events_for_keys_static::<RoomMemberEventContent, _, _>(
712                room_id,
713                &[user_id.to_owned()],
714            )
715            .await;
716        assert!(member_events?.is_empty());
717
718        // One event in store.
719        let mut changes = StateChanges::default();
720        changes
721            .stripped_state
722            .entry(room_id.to_owned())
723            .or_default()
724            .entry(StateEventType::RoomMember)
725            .or_default()
726            .insert(user_id.into(), stripped_membership_event().cast());
727        self.save_changes(&changes).await?;
728
729        assert!(self.get_member_event(room_id, user_id).await?.is_some());
730        let member_events = self
731            .get_state_events_for_keys_static::<RoomMemberEventContent, _, _>(
732                room_id,
733                &[user_id.to_owned()],
734            )
735            .await;
736        assert_eq!(member_events?.len(), 1);
737        let members = self.get_user_ids(room_id, RoomMemberships::empty()).await?;
738        assert_eq!(members.len(), 1, "We expected to find members for the room");
739
740        // Several events in store.
741        let mut changes = StateChanges::default();
742        let changes_members = changes
743            .stripped_state
744            .entry(room_id.to_owned())
745            .or_default()
746            .entry(StateEventType::RoomMember)
747            .or_default();
748        changes_members
749            .insert(second_user_id.into(), custom_stripped_membership_event(second_user_id).cast());
750        changes_members
751            .insert(third_user_id.into(), custom_stripped_membership_event(third_user_id).cast());
752        self.save_changes(&changes).await?;
753
754        assert!(self.get_member_event(room_id, second_user_id).await?.is_some());
755        assert!(self.get_member_event(room_id, third_user_id).await?.is_some());
756        let member_events = self
757            .get_state_events_for_keys_static::<RoomMemberEventContent, _, _>(
758                room_id,
759                &[user_id.to_owned(), second_user_id.to_owned(), third_user_id.to_owned()],
760            )
761            .await;
762        assert_eq!(member_events?.len(), 3);
763        let members = self.get_user_ids(room_id, RoomMemberships::empty()).await?;
764        assert_eq!(members.len(), 3, "We expected to find members for the room");
765
766        // Several events in store with one unknown.
767        let member_events = self
768            .get_state_events_for_keys_static::<RoomMemberEventContent, _, _>(
769                room_id,
770                &[
771                    user_id.to_owned(),
772                    second_user_id.to_owned(),
773                    third_user_id.to_owned(),
774                    unknown_user_id.to_owned(),
775                ],
776            )
777            .await;
778        assert_eq!(member_events?.len(), 3);
779
780        // Empty user IDs list.
781        let member_events = self
782            .get_state_events_for_keys_static::<RoomMemberEventContent, OwnedUserId, _>(
783                room_id,
784                &[],
785            )
786            .await;
787        assert!(member_events?.is_empty());
788
789        Ok(())
790    }
791
792    async fn test_power_level_saving(&self) -> TestResult {
793        let room_id = room_id!("!test_power_level_saving:localhost");
794
795        let raw_event = power_level_event();
796        let event = raw_event.deserialize()?;
797
798        assert!(
799            self.get_state_event(room_id, StateEventType::RoomPowerLevels, "").await?.is_none()
800        );
801        let mut changes = StateChanges::default();
802        changes.add_state_event(room_id, event, raw_event);
803
804        self.save_changes(&changes).await?;
805        assert!(
806            self.get_state_event(room_id, StateEventType::RoomPowerLevels, "").await?.is_some()
807        );
808
809        Ok(())
810    }
811
812    async fn test_receipts_saving(&self) -> TestResult {
813        let room_id = room_id!("!test_receipts_saving:localhost");
814
815        let first_event_id = event_id!("$1435641916114394fHBLK:matrix.org");
816        let second_event_id = event_id!("$fHBLK1435641916114394:matrix.org");
817
818        let first_receipt_ts = uint!(1436451550);
819        let second_receipt_ts = uint!(1436451653);
820        let third_receipt_ts = uint!(1436474532);
821
822        let first_receipt_event = serde_json::from_value(json!({
823            first_event_id: {
824                "m.read": {
825                    user_id(): {
826                        "ts": first_receipt_ts,
827                    }
828                }
829            }
830        }))?;
831
832        let second_receipt_event = serde_json::from_value(json!({
833            second_event_id: {
834                "m.read": {
835                    user_id(): {
836                        "ts": second_receipt_ts,
837                    }
838                }
839            }
840        }))?;
841
842        let third_receipt_event = serde_json::from_value(json!({
843            second_event_id: {
844                "m.read": {
845                    user_id(): {
846                        "ts": third_receipt_ts,
847                        "thread_id": "main",
848                    }
849                }
850            }
851        }))?;
852
853        assert!(
854            self.get_user_room_receipt_event(
855                room_id,
856                ReceiptType::Read,
857                &ReceiptThread::Unthreaded,
858                user_id()
859            )
860            .await
861            .expect("failed to read unthreaded user room receipt")
862            .is_none()
863        );
864        assert!(
865            self.get_event_room_receipt_events(
866                room_id,
867                ReceiptType::Read,
868                &ReceiptThread::Unthreaded,
869                first_event_id
870            )
871            .await
872            .expect("failed to read unthreaded event room receipt for 1")
873            .is_empty()
874        );
875        assert!(
876            self.get_event_room_receipt_events(
877                room_id,
878                ReceiptType::Read,
879                &ReceiptThread::Unthreaded,
880                second_event_id
881            )
882            .await
883            .expect("failed to read unthreaded event room receipt for 2")
884            .is_empty()
885        );
886
887        let mut changes = StateChanges::default();
888        changes.add_receipts(room_id, first_receipt_event);
889
890        self.save_changes(&changes).await?;
891        let (unthreaded_user_receipt_event_id, unthreaded_user_receipt) = self
892            .get_user_room_receipt_event(
893                room_id,
894                ReceiptType::Read,
895                &ReceiptThread::Unthreaded,
896                user_id(),
897            )
898            .await
899            .expect("failed to read unthreaded user room receipt after save")
900            .unwrap();
901        assert_eq!(unthreaded_user_receipt_event_id, first_event_id);
902        assert_eq!(unthreaded_user_receipt.ts.unwrap().0, first_receipt_ts);
903        let first_event_unthreaded_receipts = self
904            .get_event_room_receipt_events(
905                room_id,
906                ReceiptType::Read,
907                &ReceiptThread::Unthreaded,
908                first_event_id,
909            )
910            .await
911            .expect("failed to read unthreaded event room receipt for 1 after save");
912        assert_eq!(
913            first_event_unthreaded_receipts.len(),
914            1,
915            "Found a wrong number of unthreaded receipts for 1 after save"
916        );
917        assert_eq!(first_event_unthreaded_receipts[0].0, user_id());
918        assert_eq!(first_event_unthreaded_receipts[0].1.ts.unwrap().0, first_receipt_ts);
919        assert!(
920            self.get_event_room_receipt_events(
921                room_id,
922                ReceiptType::Read,
923                &ReceiptThread::Unthreaded,
924                second_event_id
925            )
926            .await
927            .expect("failed to read unthreaded event room receipt for 2 after save")
928            .is_empty()
929        );
930
931        let mut changes = StateChanges::default();
932        changes.add_receipts(room_id, second_receipt_event);
933
934        self.save_changes(&changes).await.expect("Saving works");
935        let (unthreaded_user_receipt_event_id, unthreaded_user_receipt) = self
936            .get_user_room_receipt_event(
937                room_id,
938                ReceiptType::Read,
939                &ReceiptThread::Unthreaded,
940                user_id(),
941            )
942            .await
943            .expect("Getting unthreaded user room receipt after save failed")
944            .unwrap();
945        assert_eq!(unthreaded_user_receipt_event_id, second_event_id);
946        assert_eq!(unthreaded_user_receipt.ts.unwrap().0, second_receipt_ts);
947        assert!(
948            self.get_event_room_receipt_events(
949                room_id,
950                ReceiptType::Read,
951                &ReceiptThread::Unthreaded,
952                first_event_id
953            )
954            .await
955            .expect("Getting unthreaded event room receipt events for first event failed")
956            .is_empty()
957        );
958        let second_event_unthreaded_receipts = self
959            .get_event_room_receipt_events(
960                room_id,
961                ReceiptType::Read,
962                &ReceiptThread::Unthreaded,
963                second_event_id,
964            )
965            .await
966            .expect("Getting unthreaded event room receipt events for second event failed");
967        assert_eq!(
968            second_event_unthreaded_receipts.len(),
969            1,
970            "Found a wrong number of unthreaded receipts for second event after save"
971        );
972        assert_eq!(second_event_unthreaded_receipts[0].0, user_id());
973        assert_eq!(second_event_unthreaded_receipts[0].1.ts.unwrap().0, second_receipt_ts);
974
975        assert!(
976            self.get_user_room_receipt_event(
977                room_id,
978                ReceiptType::Read,
979                &ReceiptThread::Main,
980                user_id()
981            )
982            .await
983            .expect("failed to read threaded user room receipt")
984            .is_none()
985        );
986        assert!(
987            self.get_event_room_receipt_events(
988                room_id,
989                ReceiptType::Read,
990                &ReceiptThread::Main,
991                second_event_id
992            )
993            .await
994            .expect("Getting threaded event room receipts for 2 failed")
995            .is_empty()
996        );
997
998        let mut changes = StateChanges::default();
999        changes.add_receipts(room_id, third_receipt_event);
1000
1001        self.save_changes(&changes).await.expect("Saving works");
1002        // Unthreaded receipts should not have changed.
1003        let (unthreaded_user_receipt_event_id, unthreaded_user_receipt) = self
1004            .get_user_room_receipt_event(
1005                room_id,
1006                ReceiptType::Read,
1007                &ReceiptThread::Unthreaded,
1008                user_id(),
1009            )
1010            .await
1011            .expect("Getting unthreaded user room receipt after save failed")
1012            .unwrap();
1013        assert_eq!(unthreaded_user_receipt_event_id, second_event_id);
1014        assert_eq!(unthreaded_user_receipt.ts.unwrap().0, second_receipt_ts);
1015        let second_event_unthreaded_receipts = self
1016            .get_event_room_receipt_events(
1017                room_id,
1018                ReceiptType::Read,
1019                &ReceiptThread::Unthreaded,
1020                second_event_id,
1021            )
1022            .await
1023            .expect("Getting unthreaded event room receipt events for second event failed");
1024        assert_eq!(
1025            second_event_unthreaded_receipts.len(),
1026            1,
1027            "Found a wrong number of unthreaded receipts for second event after save"
1028        );
1029        assert_eq!(second_event_unthreaded_receipts[0].0, user_id());
1030        assert_eq!(second_event_unthreaded_receipts[0].1.ts.unwrap().0, second_receipt_ts);
1031        // Threaded receipts should have changed
1032        let (threaded_user_receipt_event_id, threaded_user_receipt) = self
1033            .get_user_room_receipt_event(
1034                room_id,
1035                ReceiptType::Read,
1036                &ReceiptThread::Main,
1037                user_id(),
1038            )
1039            .await
1040            .expect("Getting threaded user room receipt after save failed")
1041            .unwrap();
1042        assert_eq!(threaded_user_receipt_event_id, second_event_id);
1043        assert_eq!(threaded_user_receipt.ts.unwrap().0, third_receipt_ts);
1044        let second_event_threaded_receipts = self
1045            .get_event_room_receipt_events(
1046                room_id,
1047                ReceiptType::Read,
1048                &ReceiptThread::Main,
1049                second_event_id,
1050            )
1051            .await
1052            .expect("Getting threaded event room receipt events for second event failed");
1053        assert_eq!(
1054            second_event_threaded_receipts.len(),
1055            1,
1056            "Found a wrong number of threaded receipts for second event after save"
1057        );
1058        assert_eq!(second_event_threaded_receipts[0].0, user_id());
1059        assert_eq!(second_event_threaded_receipts[0].1.ts.unwrap().0, third_receipt_ts);
1060
1061        Ok(())
1062    }
1063
1064    async fn test_custom_storage(&self) -> TestResult {
1065        let key = "my_key";
1066        let value = &[0, 1, 2, 3];
1067
1068        self.set_custom_value(key.as_bytes(), value.to_vec()).await?;
1069
1070        let read = self.get_custom_value(key.as_bytes()).await?;
1071
1072        assert_eq!(Some(value.as_ref()), read.as_deref());
1073
1074        Ok(())
1075    }
1076
1077    async fn test_stripped_non_stripped(&self) -> TestResult {
1078        let room_id = room_id!("!test_stripped_non_stripped:localhost");
1079        let user_id = user_id();
1080
1081        assert!(self.get_member_event(room_id, user_id).await?.is_none());
1082        assert_eq!(self.get_room_infos(&RoomLoadSettings::default()).await?.len(), 0);
1083
1084        let mut changes = StateChanges::default();
1085        changes
1086            .state
1087            .entry(room_id.to_owned())
1088            .or_default()
1089            .entry(StateEventType::RoomMember)
1090            .or_default()
1091            .insert(user_id.into(), membership_event().cast());
1092        changes.add_room(RoomInfo::new(room_id, RoomState::Left));
1093        self.save_changes(&changes).await?;
1094
1095        let member_event = self.get_member_event(room_id, user_id).await?.unwrap().deserialize()?;
1096        assert!(matches!(member_event, MemberEvent::Sync(_)));
1097        assert_eq!(self.get_room_infos(&RoomLoadSettings::default()).await?.len(), 1);
1098
1099        let members = self.get_user_ids(room_id, RoomMemberships::empty()).await?;
1100        assert_eq!(members, vec![user_id.to_owned()]);
1101
1102        let mut changes = StateChanges::default();
1103        changes.add_stripped_member(room_id, user_id, custom_stripped_membership_event(user_id));
1104        changes.add_room(RoomInfo::new(room_id, RoomState::Invited));
1105        self.save_changes(&changes).await?;
1106
1107        let member_event = self.get_member_event(room_id, user_id).await?.unwrap().deserialize()?;
1108        assert!(matches!(member_event, MemberEvent::Stripped(_)));
1109        assert_eq!(self.get_room_infos(&RoomLoadSettings::default()).await?.len(), 1);
1110
1111        let members = self.get_user_ids(room_id, RoomMemberships::empty()).await?;
1112        assert_eq!(members, vec![user_id.to_owned()]);
1113
1114        Ok(())
1115    }
1116
1117    async fn test_stripped_state_is_kept_across_saves(&self) -> TestResult {
1118        // The server sends `invite_state`/`knock_state` once, so it must
1119        // survive any later save.
1120        for (room_id, room_state) in [
1121            (room_id!("!test_stripped_state_invited:localhost"), RoomState::Invited),
1122            (room_id!("!test_stripped_state_knocked:localhost"), RoomState::Knocked),
1123        ] {
1124            let user_id = user_id();
1125
1126            let mut changes = StateChanges::default();
1127            changes.add_stripped_member(
1128                room_id,
1129                user_id,
1130                custom_stripped_membership_event(user_id),
1131            );
1132
1133            let f = EventFactory::new().sender(user_id).room(room_id);
1134            let stripped_name_raw: Raw<AnyStrippedStateEvent> = f.room_name("room name").into();
1135            let stripped_name_event =
1136                RawStateEventWithKeys::try_from_raw_state_event(stripped_name_raw).unwrap();
1137            changes
1138                .stripped_state
1139                .entry(room_id.to_owned())
1140                .or_default()
1141                .entry(stripped_name_event.event_type)
1142                .or_default()
1143                .insert(stripped_name_event.state_key, stripped_name_event.raw);
1144
1145            changes.add_room(RoomInfo::new(room_id, room_state));
1146            self.save_changes(&changes).await?;
1147
1148            assert!(
1149                self.get_state_event(room_id, StateEventType::RoomName, "").await?.is_some(),
1150                "{room_state:?}: the stripped room name must be saved"
1151            );
1152            let member_event =
1153                self.get_member_event(room_id, user_id).await?.unwrap().deserialize()?;
1154            assert_matches!(member_event, MemberEvent::Stripped(_));
1155
1156            // A later sync only carries the room info.
1157            let mut changes = StateChanges::default();
1158            changes.add_room(RoomInfo::new(room_id, room_state));
1159            self.save_changes(&changes).await?;
1160
1161            assert!(
1162                self.get_state_event(room_id, StateEventType::RoomName, "").await?.is_some(),
1163                "{room_state:?}: the stripped room name must survive a room info save"
1164            );
1165            assert!(
1166                self.get_member_event(room_id, user_id).await?.is_some(),
1167                "{room_state:?}: the stripped member must survive a room info save"
1168            );
1169            assert_eq!(
1170                self.get_user_ids(room_id, RoomMemberships::empty()).await?,
1171                vec![user_id.to_owned()],
1172                "{room_state:?}: the stripped member must still be listed"
1173            );
1174        }
1175
1176        Ok(())
1177    }
1178
1179    async fn test_room_info_only_save_keeps_room_data(&self) -> TestResult {
1180        // A `StateChanges` carrying nothing but a `RoomInfo`, as
1181        // `BaseClient::room_knocked` saves, has nothing to put in place of what
1182        // it would delete, so it must delete nothing.
1183        for (room_id, new_state) in [
1184            (room_id!("!test_room_info_only_save_knocked:localhost"), RoomState::Knocked),
1185            (room_id!("!test_room_info_only_save_invited:localhost"), RoomState::Invited),
1186        ] {
1187            let user_id = user_id();
1188
1189            let mut changes = StateChanges::default();
1190            changes
1191                .state
1192                .entry(room_id.to_owned())
1193                .or_default()
1194                .entry(StateEventType::RoomMember)
1195                .or_default()
1196                .insert(user_id.into(), membership_event().cast());
1197
1198            let f = EventFactory::new().sender(user_id).room(room_id);
1199            let name_raw: Raw<AnySyncStateEvent> = f.room_name("room name").into();
1200            let name_event = name_raw.deserialize()?;
1201            changes.add_state_event(room_id, name_event, name_raw);
1202
1203            changes.add_room(RoomInfo::new(room_id, RoomState::Left));
1204            self.save_changes(&changes).await?;
1205
1206            let member_event =
1207                self.get_member_event(room_id, user_id).await?.unwrap().deserialize()?;
1208            assert_matches!(member_event, MemberEvent::Sync(_));
1209            assert!(self.get_state_event(room_id, StateEventType::RoomName, "").await?.is_some());
1210
1211            // Knocking on (or being invited back to) the room.
1212            let mut changes = StateChanges::default();
1213            changes.add_room(RoomInfo::new(room_id, new_state));
1214            self.save_changes(&changes).await?;
1215
1216            let member_event = self
1217                .get_member_event(room_id, user_id)
1218                .await?
1219                .unwrap_or_else(|| {
1220                    panic!("{new_state:?}: the member event must survive a room info only save")
1221                })
1222                .deserialize()?;
1223            assert_matches!(member_event, MemberEvent::Sync(_));
1224            assert!(
1225                self.get_state_event(room_id, StateEventType::RoomName, "").await?.is_some(),
1226                "{new_state:?}: the room name must survive a room info only save"
1227            );
1228            assert_eq!(
1229                self.get_user_ids(room_id, RoomMemberships::empty()).await?,
1230                vec![user_id.to_owned()],
1231                "{new_state:?}: the member must still be listed"
1232            );
1233        }
1234
1235        Ok(())
1236    }
1237
1238    async fn test_room_removal(&self) -> TestResult {
1239        let room_id = room_id();
1240        let user_id = user_id();
1241        let display_name = DisplayName::new("example");
1242        let stripped_room_id = stripped_room_id();
1243
1244        self.populate().await?;
1245
1246        {
1247            // Add a send queue request in that room.
1248            let txn = TransactionId::new();
1249            let ev =
1250                SerializableEventContent::new(&RoomMessageEventContent::text_plain("sup").into())?;
1251            self.save_send_queue_request(
1252                room_id,
1253                txn.clone(),
1254                MilliSecondsSinceUnixEpoch::now(),
1255                ev.into(),
1256                0,
1257            )
1258            .await?;
1259
1260            // Add a single dependent queue request.
1261            self.save_dependent_queued_request(
1262                room_id,
1263                &txn,
1264                ChildTransactionId::new(),
1265                MilliSecondsSinceUnixEpoch::now(),
1266                DependentQueuedRequestKind::RedactEvent,
1267            )
1268            .await?;
1269        }
1270
1271        self.remove_room(room_id).await?;
1272
1273        assert_eq!(
1274            self.get_room_infos(&RoomLoadSettings::default()).await?.len(),
1275            1,
1276            "room is still there"
1277        );
1278
1279        assert!(self.get_state_event(room_id, StateEventType::RoomName, "").await?.is_none());
1280        assert!(
1281            self.get_state_events(room_id, StateEventType::RoomTopic).await?.is_empty(),
1282            "still state events found"
1283        );
1284        assert!(self.get_profile(room_id, user_id).await?.is_none());
1285        assert!(self.get_member_event(room_id, user_id).await?.is_none());
1286        assert!(
1287            self.get_user_ids(room_id, RoomMemberships::empty()).await?.is_empty(),
1288            "still user ids found"
1289        );
1290        assert!(
1291            self.get_user_ids(room_id, RoomMemberships::INVITE).await?.is_empty(),
1292            "still invited user ids found"
1293        );
1294        assert!(
1295            self.get_user_ids(room_id, RoomMemberships::JOIN).await?.is_empty(),
1296            "still joined users found"
1297        );
1298        assert!(
1299            self.get_users_with_display_name(room_id, &display_name).await?.is_empty(),
1300            "still display names found"
1301        );
1302        assert!(
1303            self.get_room_account_data_event(room_id, RoomAccountDataEventType::Tag)
1304                .await?
1305                .is_none()
1306        );
1307        assert!(
1308            self.get_user_room_receipt_event(
1309                room_id,
1310                ReceiptType::Read,
1311                &ReceiptThread::Unthreaded,
1312                user_id
1313            )
1314            .await?
1315            .is_none()
1316        );
1317        assert!(
1318            self.get_event_room_receipt_events(
1319                room_id,
1320                ReceiptType::Read,
1321                &ReceiptThread::Unthreaded,
1322                first_receipt_event_id()
1323            )
1324            .await?
1325            .is_empty(),
1326            "still event receipts in the store"
1327        );
1328        assert!(self.load_send_queue_requests(room_id).await?.is_empty());
1329        assert!(self.load_dependent_queued_requests(room_id).await?.is_empty());
1330
1331        self.remove_room(stripped_room_id).await?;
1332
1333        assert!(
1334            self.get_room_infos(&RoomLoadSettings::default()).await?.is_empty(),
1335            "still room info found"
1336        );
1337        Ok(())
1338    }
1339
1340    async fn test_profile_removal(&self) -> TestResult {
1341        let room_id = room_id();
1342
1343        // Both the user id and invited user id get a profile in populate().
1344        let user_id = user_id();
1345        let invited_user_id = invited_user_id();
1346
1347        self.populate().await?;
1348
1349        let new_invite_member_json = json!({
1350            "content": {
1351                "avatar_url": "mxc://localhost/SEsfnsuifSDFSSEG",
1352                "displayname": "example after update",
1353                "membership": "invite",
1354                "reason": "Looking for support"
1355            },
1356            "event_id": "$143273582443PhrSm:localhost",
1357            "origin_server_ts": 1432735824,
1358            "room_id": room_id,
1359            "sender": user_id,
1360            "state_key": invited_user_id,
1361            "type": "m.room.member",
1362        });
1363        let new_invite_member_event: SyncRoomMemberEvent =
1364            serde_json::from_value(new_invite_member_json.clone())?;
1365
1366        let mut changes = StateChanges {
1367            // Both get their profiles deleted…
1368            profiles_to_delete: [(
1369                room_id.to_owned(),
1370                vec![user_id.to_owned(), invited_user_id.to_owned()],
1371            )]
1372            .into(),
1373
1374            // …but the invited user get a new profile.
1375            profiles: {
1376                let mut map = BTreeMap::default();
1377                map.insert(
1378                    room_id.to_owned(),
1379                    [(invited_user_id.to_owned(), new_invite_member_event.into())]
1380                        .into_iter()
1381                        .collect(),
1382                );
1383                map
1384            },
1385
1386            ..StateChanges::default()
1387        };
1388
1389        let raw = serde_json::from_value::<Raw<AnySyncStateEvent>>(new_invite_member_json)
1390            .expect("can create sync-state-event for topic");
1391        let event = raw.deserialize()?;
1392        changes.add_state_event(room_id, event, raw);
1393
1394        self.save_changes(&changes).await?;
1395
1396        // The profile for user has been removed.
1397        assert!(self.get_profile(room_id, user_id).await?.is_none());
1398        assert!(self.get_member_event(room_id, user_id).await?.is_some());
1399
1400        // The profile for the invited user has been updated.
1401        let invited_member_event = self.get_profile(room_id, invited_user_id).await?.unwrap();
1402        assert_eq!(
1403            invited_member_event.content.displayname.as_deref(),
1404            Some("example after update")
1405        );
1406        assert!(self.get_member_event(room_id, invited_user_id).await?.is_some());
1407
1408        Ok(())
1409    }
1410
1411    async fn test_presence_saving(&self) -> TestResult {
1412        let user_id = user_id();
1413        let second_user_id = user_id!("@second:localhost");
1414        let third_user_id = user_id!("@third:localhost");
1415        let unknown_user_id = user_id!("@unknown:localhost");
1416
1417        // No event in store.
1418        let mut user_ids = vec![user_id.to_owned()];
1419        let presence_event = self.get_presence_event(user_id).await;
1420        assert!(presence_event?.is_none());
1421        let presence_events = self.get_presence_events(&user_ids).await;
1422        assert!(presence_events?.is_empty());
1423
1424        // One event in store.
1425        let mut changes = StateChanges::default();
1426        changes.presence.insert(user_id.to_owned(), custom_presence_event(user_id));
1427        self.save_changes(&changes).await?;
1428
1429        let presence_event = self.get_presence_event(user_id).await;
1430        assert!(presence_event?.is_some());
1431        let presence_events = self.get_presence_events(&user_ids).await;
1432        assert_eq!(presence_events?.len(), 1);
1433
1434        // Several events in store.
1435        let mut changes = StateChanges::default();
1436        changes.presence.insert(second_user_id.to_owned(), custom_presence_event(second_user_id));
1437        changes.presence.insert(third_user_id.to_owned(), custom_presence_event(third_user_id));
1438        self.save_changes(&changes).await?;
1439
1440        user_ids.extend([second_user_id.to_owned(), third_user_id.to_owned()]);
1441        let presence_event = self.get_presence_event(second_user_id).await;
1442        assert!(presence_event?.is_some());
1443        let presence_event = self.get_presence_event(third_user_id).await;
1444        assert!(presence_event?.is_some());
1445        let presence_events = self.get_presence_events(&user_ids).await;
1446        assert_eq!(presence_events?.len(), 3);
1447
1448        // Several events in store with one unknown.
1449        user_ids.push(unknown_user_id.to_owned());
1450        let member_events = self.get_presence_events(&user_ids).await;
1451        assert_eq!(member_events?.len(), 3);
1452
1453        // Empty user IDs list.
1454        let presence_events = self.get_presence_events(&[]).await;
1455        assert!(presence_events?.is_empty());
1456
1457        Ok(())
1458    }
1459
1460    async fn test_display_names_saving(&self) -> TestResult {
1461        let room_id = room_id!("!test_display_names_saving:localhost");
1462        let user_id = user_id();
1463        let user_display_name = DisplayName::new("User");
1464        let second_user_id = user_id!("@second:localhost");
1465        let third_user_id = user_id!("@third:localhost");
1466        let other_display_name = DisplayName::new("Raoul");
1467        let unknown_display_name = DisplayName::new("Unknown");
1468
1469        // No event in store.
1470        let mut display_names = vec![user_display_name.to_owned()];
1471        let users = self.get_users_with_display_name(room_id, &user_display_name).await?;
1472        assert!(users.is_empty());
1473        let names = self.get_users_with_display_names(room_id, &display_names).await?;
1474        assert!(names.is_empty());
1475
1476        // One event in store.
1477        let mut changes = StateChanges::default();
1478        changes
1479            .ambiguity_maps
1480            .entry(room_id.to_owned())
1481            .or_default()
1482            .insert(user_display_name.to_owned(), [user_id.to_owned()].into());
1483        self.save_changes(&changes).await?;
1484
1485        let users = self.get_users_with_display_name(room_id, &user_display_name).await?;
1486        assert_eq!(users.len(), 1);
1487        let names = self.get_users_with_display_names(room_id, &display_names).await?;
1488        assert_eq!(names.len(), 1);
1489        assert_eq!(names.get(&user_display_name).unwrap().len(), 1);
1490
1491        // Several events in store.
1492        let mut changes = StateChanges::default();
1493        changes.ambiguity_maps.entry(room_id.to_owned()).or_default().insert(
1494            other_display_name.to_owned(),
1495            [second_user_id.to_owned(), third_user_id.to_owned()].into(),
1496        );
1497        self.save_changes(&changes).await?;
1498
1499        display_names.push(other_display_name.to_owned());
1500        let users = self.get_users_with_display_name(room_id, &user_display_name).await?;
1501        assert_eq!(users.len(), 1);
1502        let users = self.get_users_with_display_name(room_id, &other_display_name).await?;
1503        assert_eq!(users.len(), 2);
1504        let names = self.get_users_with_display_names(room_id, &display_names).await?;
1505        assert_eq!(names.len(), 2);
1506        assert_eq!(names.get(&user_display_name).unwrap().len(), 1);
1507        assert_eq!(names.get(&other_display_name).unwrap().len(), 2);
1508
1509        // Several events in store with one unknown.
1510        display_names.push(unknown_display_name.to_owned());
1511        let names = self.get_users_with_display_names(room_id, &display_names).await?;
1512        assert_eq!(names.len(), 2);
1513
1514        // Empty user IDs list.
1515        let names = self.get_users_with_display_names(room_id, &[]).await?;
1516        assert!(names.is_empty());
1517
1518        Ok(())
1519    }
1520
1521    #[allow(clippy::needless_range_loop)]
1522    async fn test_send_queue(&self) -> TestResult {
1523        let room_id = room_id!("!test_send_queue:localhost");
1524
1525        // No queued event in store at first.
1526        let events = self.load_send_queue_requests(room_id).await?;
1527        assert!(events.is_empty());
1528
1529        // Saving one thing should work.
1530        let txn0 = TransactionId::new();
1531        let event0 =
1532            SerializableEventContent::new(&RoomMessageEventContent::text_plain("msg0").into())?;
1533        self.save_send_queue_request(
1534            room_id,
1535            txn0.clone(),
1536            MilliSecondsSinceUnixEpoch::now(),
1537            event0.into(),
1538            0,
1539        )
1540        .await?;
1541
1542        // Reading it will work.
1543        let pending = self.load_send_queue_requests(room_id).await?;
1544
1545        assert_eq!(pending.len(), 1);
1546        {
1547            assert_eq!(pending[0].transaction_id, txn0);
1548
1549            let deserialized = pending[0].as_event().unwrap().deserialize()?;
1550            assert_let!(AnyMessageLikeEventContent::RoomMessage(content) = deserialized);
1551            assert_eq!(content.body(), "msg0");
1552
1553            assert!(!pending[0].is_wedged());
1554        }
1555
1556        // Saving another three things should work.
1557        for i in 1..=3 {
1558            let txn = TransactionId::new();
1559            let event = SerializableEventContent::new(
1560                &RoomMessageEventContent::text_plain(format!("msg{i}")).into(),
1561            )?;
1562
1563            self.save_send_queue_request(
1564                room_id,
1565                txn,
1566                MilliSecondsSinceUnixEpoch::now(),
1567                event.into(),
1568                0,
1569            )
1570            .await?;
1571        }
1572
1573        // Reading all the events should work.
1574        let pending = self.load_send_queue_requests(room_id).await?;
1575
1576        // All the events should be retrieved, in the same order.
1577        assert_eq!(pending.len(), 4);
1578
1579        assert_eq!(pending[0].transaction_id, txn0);
1580
1581        for i in 0..4 {
1582            let deserialized = pending[i].as_event().unwrap().deserialize()?;
1583            assert_let!(AnyMessageLikeEventContent::RoomMessage(content) = deserialized);
1584            assert_eq!(content.body(), format!("msg{i}"));
1585            assert!(!pending[i].is_wedged());
1586        }
1587
1588        // Marking an event as wedged works.
1589        let txn2 = &pending[2].transaction_id;
1590        self.update_send_queue_request_status(
1591            room_id,
1592            txn2,
1593            Some(QueueWedgeError::GenericApiError { msg: "Oops".to_owned() }),
1594        )
1595        .await?;
1596
1597        // And it is reflected.
1598        let pending = self.load_send_queue_requests(room_id).await?;
1599
1600        // All the events should be retrieved, in the same order.
1601        assert_eq!(pending.len(), 4);
1602        assert_eq!(pending[0].transaction_id, txn0);
1603        assert_eq!(pending[2].transaction_id, *txn2);
1604        assert!(pending[2].is_wedged());
1605        let error = pending[2].clone().error.unwrap();
1606        let generic_error = assert_matches!(error, QueueWedgeError::GenericApiError { msg } => msg);
1607        assert_eq!(generic_error, "Oops");
1608        for i in 0..4 {
1609            if i != 2 {
1610                assert!(!pending[i].is_wedged());
1611            }
1612        }
1613
1614        // Updating an event will work, and reset its wedged state to false.
1615        let event0 = SerializableEventContent::new(
1616            &RoomMessageEventContent::text_plain("wow that's a cool test").into(),
1617        )?;
1618        self.update_send_queue_request(room_id, txn2, event0.into()).await?;
1619
1620        // And it is reflected.
1621        let pending = self.load_send_queue_requests(room_id).await?;
1622
1623        assert_eq!(pending.len(), 4);
1624        {
1625            assert_eq!(pending[2].transaction_id, *txn2);
1626
1627            let deserialized = pending[2].as_event().unwrap().deserialize()?;
1628            assert_let!(AnyMessageLikeEventContent::RoomMessage(content) = deserialized);
1629            assert_eq!(content.body(), "wow that's a cool test");
1630
1631            assert!(!pending[2].is_wedged());
1632
1633            for i in 0..4 {
1634                if i != 2 {
1635                    let deserialized = pending[i].as_event().unwrap().deserialize()?;
1636                    assert_let!(AnyMessageLikeEventContent::RoomMessage(content) = deserialized);
1637                    assert_eq!(content.body(), format!("msg{i}"));
1638
1639                    assert!(!pending[i].is_wedged());
1640                }
1641            }
1642        }
1643
1644        // Removing an event works.
1645        self.remove_send_queue_request(room_id, &txn0).await?;
1646
1647        // And it is reflected.
1648        let pending = self.load_send_queue_requests(room_id).await?;
1649
1650        assert_eq!(pending.len(), 3);
1651        assert_eq!(pending[1].transaction_id, *txn2);
1652        for i in 0..3 {
1653            assert_ne!(pending[i].transaction_id, txn0);
1654        }
1655
1656        // Now add one event for two other rooms, remove one of the events, and
1657        // then query all the rooms which have outstanding unsent events.
1658
1659        // Add one event for room2.
1660        let room_id2 = room_id!("!test_send_queue_two:localhost");
1661        {
1662            let txn = TransactionId::new();
1663            let event = SerializableEventContent::new(
1664                &RoomMessageEventContent::text_plain("room2").into(),
1665            )?;
1666            self.save_send_queue_request(
1667                room_id2,
1668                txn.clone(),
1669                MilliSecondsSinceUnixEpoch::now(),
1670                event.into(),
1671                0,
1672            )
1673            .await?;
1674        }
1675
1676        // Add and remove one event for room3.
1677        {
1678            let room_id3 = room_id!("!test_send_queue_three:localhost");
1679            let txn = TransactionId::new();
1680            let event = SerializableEventContent::new(
1681                &RoomMessageEventContent::text_plain("room3").into(),
1682            )?;
1683            self.save_send_queue_request(
1684                room_id3,
1685                txn.clone(),
1686                MilliSecondsSinceUnixEpoch::now(),
1687                event.into(),
1688                0,
1689            )
1690            .await?;
1691
1692            self.remove_send_queue_request(room_id3, &txn).await?;
1693        }
1694
1695        // Query all the rooms which have unsent events. Per the previous steps,
1696        // it should be room1 and room2, not room3.
1697        let outstanding_rooms = self.load_rooms_with_unsent_requests().await?;
1698        assert_eq!(outstanding_rooms.len(), 2);
1699        assert!(outstanding_rooms.iter().any(|room| room == room_id));
1700        assert!(outstanding_rooms.iter().any(|room| room == room_id2));
1701
1702        Ok(())
1703    }
1704
1705    async fn test_send_queue_priority(&self) -> TestResult {
1706        let room_id = room_id!("!test_send_queue:localhost");
1707
1708        // No queued event in store at first.
1709        let events = self.load_send_queue_requests(room_id).await?;
1710        assert!(events.is_empty());
1711
1712        // Saving one request should work.
1713        let low0_txn = TransactionId::new();
1714        let ev0 =
1715            SerializableEventContent::new(&RoomMessageEventContent::text_plain("low0").into())?;
1716        self.save_send_queue_request(
1717            room_id,
1718            low0_txn.clone(),
1719            MilliSecondsSinceUnixEpoch::now(),
1720            ev0.into(),
1721            2,
1722        )
1723        .await?;
1724
1725        // Saving one request with higher priority should work.
1726        let high_txn = TransactionId::new();
1727        let ev1 =
1728            SerializableEventContent::new(&RoomMessageEventContent::text_plain("high").into())?;
1729        self.save_send_queue_request(
1730            room_id,
1731            high_txn.clone(),
1732            MilliSecondsSinceUnixEpoch::now(),
1733            ev1.into(),
1734            10,
1735        )
1736        .await?;
1737
1738        // Saving another request with the low priority should work.
1739        let low1_txn = TransactionId::new();
1740        let ev2 =
1741            SerializableEventContent::new(&RoomMessageEventContent::text_plain("low1").into())?;
1742        self.save_send_queue_request(
1743            room_id,
1744            low1_txn.clone(),
1745            MilliSecondsSinceUnixEpoch::now(),
1746            ev2.into(),
1747            2,
1748        )
1749        .await?;
1750
1751        // The requests should be ordered from higher priority to lower, and
1752        // when equal, should use the insertion order instead.
1753        let pending = self.load_send_queue_requests(room_id).await?;
1754
1755        assert_eq!(pending.len(), 3);
1756        {
1757            assert_eq!(pending[0].transaction_id, high_txn);
1758
1759            let deserialized = pending[0].as_event().unwrap().deserialize()?;
1760            assert_let!(AnyMessageLikeEventContent::RoomMessage(content) = deserialized);
1761            assert_eq!(content.body(), "high");
1762        }
1763
1764        {
1765            assert_eq!(pending[1].transaction_id, low0_txn);
1766
1767            let deserialized = pending[1].as_event().unwrap().deserialize()?;
1768            assert_let!(AnyMessageLikeEventContent::RoomMessage(content) = deserialized);
1769            assert_eq!(content.body(), "low0");
1770        }
1771
1772        {
1773            assert_eq!(pending[2].transaction_id, low1_txn);
1774
1775            let deserialized = pending[2].as_event().unwrap().deserialize()?;
1776            assert_let!(AnyMessageLikeEventContent::RoomMessage(content) = deserialized);
1777            assert_eq!(content.body(), "low1");
1778        }
1779
1780        Ok(())
1781    }
1782
1783    #[cfg(not(feature = "unstable-msc4354"))]
1784    async fn test_send_queue_sticky_events(&self) -> TestResult {
1785        Ok(()) // Dummy test when the feature is off because we cannot check features where the method is registered.
1786    }
1787
1788    #[cfg(feature = "unstable-msc4354")]
1789    async fn test_send_queue_sticky_events(&self) -> TestResult {
1790        use ruma::events::sticky::StickyDurationMs;
1791
1792        let room_id = room_id!("!test_send_queue_sticky_events:localhost");
1793
1794        // A regular event isn't sticky.
1795        let content =
1796            SerializableEventContent::new(&RoomMessageEventContent::text_plain("regular").into())?;
1797        let regular_txn = TransactionId::new();
1798        self.save_send_queue_request(
1799            room_id,
1800            regular_txn.clone(),
1801            MilliSecondsSinceUnixEpoch::now(),
1802            content.into(),
1803            0,
1804        )
1805        .await?;
1806
1807        // A sticky event keeps its duration across a round-trip.
1808        let content =
1809            SerializableEventContent::new(&RoomMessageEventContent::text_plain("sticky").into())?;
1810        let sticky_txn = TransactionId::new();
1811        self.save_send_queue_request(
1812            room_id,
1813            sticky_txn.clone(),
1814            MilliSecondsSinceUnixEpoch::now(),
1815            QueuedRequestKind::Event {
1816                content,
1817                sticky_duration: Some(StickyDurationMs::new_clamped(300_000u32)),
1818            },
1819            0,
1820        )
1821        .await?;
1822
1823        let pending = self.load_send_queue_requests(room_id).await?;
1824        assert_eq!(pending.len(), 2);
1825
1826        assert_eq!(pending[0].transaction_id, regular_txn);
1827        assert_matches!(&pending[0].kind, QueuedRequestKind::Event { sticky_duration: None, .. });
1828
1829        assert_eq!(pending[1].transaction_id, sticky_txn);
1830        assert_matches!(
1831            &pending[1].kind,
1832            QueuedRequestKind::Event { sticky_duration: Some(duration), .. } => {
1833                assert_eq!(duration.get(), 300_000);
1834            }
1835        );
1836
1837        Ok(())
1838    }
1839
1840    async fn test_send_queue_dependents(&self) -> TestResult {
1841        let room_id = room_id!("!test_send_queue_dependents:localhost");
1842
1843        // Save one send queue event to start with.
1844        let txn0 = TransactionId::new();
1845        let event0 =
1846            SerializableEventContent::new(&RoomMessageEventContent::text_plain("hey").into())?;
1847        self.save_send_queue_request(
1848            room_id,
1849            txn0.clone(),
1850            MilliSecondsSinceUnixEpoch::now(),
1851            event0.clone().into(),
1852            0,
1853        )
1854        .await?;
1855
1856        // No dependents, to start with.
1857        assert!(self.load_dependent_queued_requests(room_id).await?.is_empty());
1858
1859        // Save a redaction for that event.
1860        let child_txn = ChildTransactionId::new();
1861        self.save_dependent_queued_request(
1862            room_id,
1863            &txn0,
1864            child_txn.clone(),
1865            MilliSecondsSinceUnixEpoch::now(),
1866            DependentQueuedRequestKind::RedactEvent,
1867        )
1868        .await?;
1869
1870        // It worked.
1871        let dependents = self.load_dependent_queued_requests(room_id).await?;
1872        assert_eq!(dependents.len(), 1);
1873        assert_eq!(dependents[0].parent_transaction_id, txn0);
1874        assert_eq!(dependents[0].own_transaction_id, child_txn);
1875        assert!(dependents[0].parent_key.is_none());
1876        assert_matches!(dependents[0].kind, DependentQueuedRequestKind::RedactEvent);
1877
1878        // Update the event id.
1879        let (event, event_type) = event0.raw();
1880        let event_id = owned_event_id!("$1");
1881        let num_updated = self
1882            .mark_dependent_queued_requests_as_ready(
1883                room_id,
1884                &txn0,
1885                SentRequestKey::Event {
1886                    event_id: event_id.clone(),
1887                    event: event.clone(),
1888                    event_type: event_type.to_owned(),
1889                },
1890            )
1891            .await?;
1892        assert_eq!(num_updated, 1);
1893
1894        // It worked.
1895        let dependents = self.load_dependent_queued_requests(room_id).await?;
1896        assert_eq!(dependents.len(), 1);
1897        assert_eq!(dependents[0].parent_transaction_id, txn0);
1898        assert_eq!(dependents[0].own_transaction_id, child_txn);
1899        assert_matches!(
1900            dependents[0].parent_key.as_ref(),
1901            Some(SentRequestKey::Event {
1902                event_id: received_event_id,
1903                event: received_event,
1904                event_type: received_event_type
1905            }) => {
1906                assert_eq!(received_event_id, &event_id);
1907                assert_eq!(received_event.json().to_string(), event.json().to_string());
1908                assert_eq!(received_event_type.as_str(), event_type);
1909            }
1910        );
1911        assert_matches!(dependents[0].kind, DependentQueuedRequestKind::RedactEvent);
1912
1913        // Now remove it.
1914        let removed = self
1915            .remove_dependent_queued_request(room_id, &dependents[0].own_transaction_id)
1916            .await?;
1917        assert!(removed);
1918
1919        // It worked.
1920        assert!(self.load_dependent_queued_requests(room_id).await?.is_empty());
1921
1922        // Now, inserting a dependent event and removing the original send queue
1923        // event will NOT remove the dependent event.
1924        let txn1 = TransactionId::new();
1925        let event1 =
1926            SerializableEventContent::new(&RoomMessageEventContent::text_plain("hey2").into())?;
1927        self.save_send_queue_request(
1928            room_id,
1929            txn1.clone(),
1930            MilliSecondsSinceUnixEpoch::now(),
1931            event1.into(),
1932            0,
1933        )
1934        .await?;
1935
1936        self.save_dependent_queued_request(
1937            room_id,
1938            &txn0,
1939            ChildTransactionId::new(),
1940            MilliSecondsSinceUnixEpoch::now(),
1941            DependentQueuedRequestKind::RedactEvent,
1942        )
1943        .await?;
1944        assert_eq!(self.load_dependent_queued_requests(room_id).await?.len(), 1);
1945
1946        self.save_dependent_queued_request(
1947            room_id,
1948            &txn1,
1949            ChildTransactionId::new(),
1950            MilliSecondsSinceUnixEpoch::now(),
1951            DependentQueuedRequestKind::EditEvent {
1952                new_content: SerializableEventContent::new(
1953                    &RoomMessageEventContent::text_plain("edit").into(),
1954                )?,
1955            },
1956        )
1957        .await?;
1958        assert_eq!(self.load_dependent_queued_requests(room_id).await?.len(), 2);
1959
1960        // Remove event0 / txn0.
1961        let removed = self.remove_send_queue_request(room_id, &txn0).await?;
1962        assert!(removed);
1963
1964        // This has removed none of the dependent events.
1965        let dependents = self.load_dependent_queued_requests(room_id).await?;
1966        assert_eq!(dependents.len(), 2);
1967
1968        Ok(())
1969    }
1970
1971    async fn test_update_send_queue_dependent(&self) -> TestResult {
1972        let room_id = room_id!("!test_send_queue_dependents:localhost");
1973
1974        let txn = TransactionId::new();
1975
1976        // Save a dependent redaction for an event.
1977        let child_txn = ChildTransactionId::new();
1978
1979        self.save_dependent_queued_request(
1980            room_id,
1981            &txn,
1982            child_txn.clone(),
1983            MilliSecondsSinceUnixEpoch::now(),
1984            DependentQueuedRequestKind::RedactEvent,
1985        )
1986        .await?;
1987
1988        // It worked.
1989        let dependents = self.load_dependent_queued_requests(room_id).await?;
1990        assert_eq!(dependents.len(), 1);
1991        assert_eq!(dependents[0].parent_transaction_id, txn);
1992        assert_eq!(dependents[0].own_transaction_id, child_txn);
1993        assert!(dependents[0].parent_key.is_none());
1994        assert_matches!(dependents[0].kind, DependentQueuedRequestKind::RedactEvent);
1995
1996        // Make it a reaction, instead of a redaction.
1997        self.update_dependent_queued_request(
1998            room_id,
1999            &child_txn,
2000            DependentQueuedRequestKind::ReactEvent { key: "👍".to_owned() },
2001        )
2002        .await?;
2003
2004        // It worked.
2005        let dependents = self.load_dependent_queued_requests(room_id).await?;
2006        assert_eq!(dependents.len(), 1);
2007        assert_eq!(dependents[0].parent_transaction_id, txn);
2008        assert_eq!(dependents[0].own_transaction_id, child_txn);
2009        assert!(dependents[0].parent_key.is_none());
2010        assert_matches!(
2011            &dependents[0].kind,
2012            DependentQueuedRequestKind::ReactEvent { key } => {
2013                assert_eq!(key, "👍");
2014            }
2015        );
2016
2017        Ok(())
2018    }
2019
2020    async fn test_get_room_infos(&self) -> TestResult {
2021        let room_id_0 = room_id!("!r0");
2022        let room_id_1 = room_id!("!r1");
2023        let room_id_2 = room_id!("!r2");
2024
2025        // There is no room for the moment.
2026        {
2027            assert_eq!(self.get_room_infos(&RoomLoadSettings::default()).await?.len(), 0);
2028        }
2029
2030        // Save rooms.
2031        let mut changes = StateChanges::default();
2032        changes.add_room(RoomInfo::new(room_id_0, RoomState::Joined));
2033        changes.add_room(RoomInfo::new(room_id_1, RoomState::Joined));
2034        self.save_changes(&changes).await?;
2035
2036        // We can find all the rooms with `RoomLoadSettings::All`.
2037        {
2038            let mut all_rooms = self.get_room_infos(&RoomLoadSettings::All).await?;
2039
2040            // (We need to sort by `room_id` so that the test is stable across
2041            // all `StateStore` implementations).
2042            all_rooms.sort_by(|a, b| a.room_id.cmp(&b.room_id));
2043
2044            assert_eq!(all_rooms.len(), 2);
2045            assert_eq!(all_rooms[0].room_id, room_id_0);
2046            assert_eq!(all_rooms[1].room_id, room_id_1);
2047        }
2048
2049        // We can find a single room with `RoomLoadSettings::One`.
2050        {
2051            let all_rooms =
2052                self.get_room_infos(&RoomLoadSettings::One(room_id_1.to_owned())).await?;
2053
2054            assert_eq!(all_rooms.len(), 1);
2055            assert_eq!(all_rooms[0].room_id, room_id_1);
2056        }
2057
2058        // `RoomLoadSetting::One` can result in loading zero room if the room is
2059        // unknown.
2060        {
2061            let all_rooms =
2062                self.get_room_infos(&RoomLoadSettings::One(room_id_2.to_owned())).await?;
2063
2064            assert_eq!(all_rooms.len(), 0);
2065        }
2066
2067        Ok(())
2068    }
2069
2070    async fn test_thread_subscriptions(&self) -> TestResult {
2071        let first_thread = event_id!("$t1");
2072        let second_thread = event_id!("$t2");
2073
2074        // At first, there is no thread subscription.
2075        let maybe_sub = self.load_thread_subscription(room_id(), first_thread).await?;
2076        assert!(maybe_sub.is_none());
2077
2078        let maybe_sub = self.load_thread_subscription(room_id(), second_thread).await?;
2079        assert!(maybe_sub.is_none());
2080
2081        // Setting the thread subscription works.
2082        self.upsert_thread_subscriptions(vec![(
2083            room_id(),
2084            first_thread,
2085            StoredThreadSubscription {
2086                status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2087                bump_stamp: None,
2088            },
2089        )])
2090        .await?;
2091
2092        self.upsert_thread_subscriptions(vec![(
2093            room_id(),
2094            second_thread,
2095            StoredThreadSubscription {
2096                status: ThreadSubscriptionStatus::Subscribed { automatic: false },
2097                bump_stamp: None,
2098            },
2099        )])
2100        .await?;
2101
2102        // Now, reading the thread subscription returns the expected status.
2103        let maybe_sub = self.load_thread_subscription(room_id(), first_thread).await?;
2104        assert_eq!(
2105            maybe_sub,
2106            Some(StoredThreadSubscription {
2107                status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2108                bump_stamp: None,
2109            })
2110        );
2111
2112        let maybe_sub = self.load_thread_subscription(room_id(), second_thread).await?;
2113        assert_eq!(
2114            maybe_sub,
2115            Some(StoredThreadSubscription {
2116                status: ThreadSubscriptionStatus::Subscribed { automatic: false },
2117                bump_stamp: None,
2118            })
2119        );
2120
2121        // We can override the thread subscription status.
2122        self.upsert_thread_subscriptions(vec![(
2123            room_id(),
2124            first_thread,
2125            StoredThreadSubscription {
2126                status: ThreadSubscriptionStatus::Unsubscribed,
2127                bump_stamp: None,
2128            },
2129        )])
2130        .await?;
2131
2132        // And it's correctly reflected.
2133        let maybe_sub = self.load_thread_subscription(room_id(), first_thread).await?;
2134        assert_eq!(
2135            maybe_sub,
2136            Some(StoredThreadSubscription {
2137                status: ThreadSubscriptionStatus::Unsubscribed,
2138                bump_stamp: None,
2139            })
2140        );
2141
2142        // And the second thread is still subscribed.
2143        let maybe_sub = self.load_thread_subscription(room_id(), second_thread).await?;
2144        assert_eq!(
2145            maybe_sub,
2146            Some(StoredThreadSubscription {
2147                status: ThreadSubscriptionStatus::Subscribed { automatic: false },
2148                bump_stamp: None,
2149            })
2150        );
2151
2152        // We can remove a thread subscription.
2153        self.remove_thread_subscription(room_id(), second_thread).await?;
2154
2155        // And it's correctly reflected.
2156        let maybe_sub = self.load_thread_subscription(room_id(), second_thread).await?;
2157        assert_eq!(maybe_sub, None);
2158
2159        // And the first thread is still unsubscribed.
2160        let maybe_sub = self.load_thread_subscription(room_id(), first_thread).await?;
2161        assert_eq!(
2162            maybe_sub,
2163            Some(StoredThreadSubscription {
2164                status: ThreadSubscriptionStatus::Unsubscribed,
2165                bump_stamp: None,
2166            })
2167        );
2168
2169        // Removing a thread subscription for an unknown thread is a no-op.
2170        self.remove_thread_subscription(room_id(), second_thread).await?;
2171
2172        Ok(())
2173    }
2174
2175    async fn test_thread_subscriptions_bulk_upsert(&self) -> TestResult {
2176        let threads = [
2177            event_id!("$t1"),
2178            event_id!("$t2"),
2179            event_id!("$t3"),
2180            event_id!("$t4"),
2181            event_id!("$t5"),
2182            event_id!("$t6"),
2183        ];
2184        // Helper for building the input for `upsert_thread_subscriptions()`,
2185        // which is of the type: Vec<(&RoomId, &EventId,
2186        // StoredThreadSubscription)>
2187        let build_subscription_updates = |subs: &[StoredThreadSubscription]| {
2188            threads
2189                .iter()
2190                .zip(subs)
2191                .map(|(&event_id, &sub)| (room_id(), event_id, sub))
2192                .collect::<Vec<_>>()
2193        };
2194
2195        // Test bump_stamp logic
2196        let initial_subscriptions = build_subscription_updates(&[
2197            StoredThreadSubscription {
2198                status: ThreadSubscriptionStatus::Unsubscribed,
2199                bump_stamp: None,
2200            },
2201            StoredThreadSubscription {
2202                status: ThreadSubscriptionStatus::Unsubscribed,
2203                bump_stamp: Some(14),
2204            },
2205            StoredThreadSubscription {
2206                status: ThreadSubscriptionStatus::Unsubscribed,
2207                bump_stamp: None,
2208            },
2209            StoredThreadSubscription {
2210                status: ThreadSubscriptionStatus::Unsubscribed,
2211                bump_stamp: Some(210),
2212            },
2213            StoredThreadSubscription {
2214                status: ThreadSubscriptionStatus::Unsubscribed,
2215                bump_stamp: Some(5),
2216            },
2217            StoredThreadSubscription {
2218                status: ThreadSubscriptionStatus::Unsubscribed,
2219                bump_stamp: Some(100),
2220            },
2221        ]);
2222
2223        let update_subscriptions = build_subscription_updates(&[
2224            StoredThreadSubscription {
2225                status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2226                bump_stamp: None,
2227            },
2228            StoredThreadSubscription {
2229                status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2230                bump_stamp: None,
2231            },
2232            StoredThreadSubscription {
2233                status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2234                bump_stamp: Some(1101),
2235            },
2236            StoredThreadSubscription {
2237                status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2238                bump_stamp: Some(222),
2239            },
2240            StoredThreadSubscription {
2241                status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2242                bump_stamp: Some(1),
2243            },
2244            StoredThreadSubscription {
2245                status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2246                bump_stamp: Some(100),
2247            },
2248        ]);
2249
2250        let expected_subscriptions = build_subscription_updates(&[
2251            // Status should be updated, because prev and new bump_stamp are both None
2252            StoredThreadSubscription {
2253                status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2254                bump_stamp: None,
2255            },
2256            // Status should be updated, but keep initial bump_stamp (new is None)
2257            StoredThreadSubscription {
2258                status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2259                bump_stamp: Some(14),
2260            },
2261            // Status should be updated and also bump_stamp should be updated (initial was None)
2262            StoredThreadSubscription {
2263                status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2264                bump_stamp: Some(1101),
2265            },
2266            // Status should be updated and also bump_stamp should be updated (initial was lower)
2267            StoredThreadSubscription {
2268                status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2269                bump_stamp: Some(222),
2270            },
2271            // Status shouldn't change, as new bump_stamp is lower
2272            StoredThreadSubscription {
2273                status: ThreadSubscriptionStatus::Unsubscribed,
2274                bump_stamp: Some(5),
2275            },
2276            // Status shouldn't change, as bump_stamp is equal to the previous one
2277            StoredThreadSubscription {
2278                status: ThreadSubscriptionStatus::Unsubscribed,
2279                bump_stamp: Some(100),
2280            },
2281        ]);
2282
2283        // Set the initial subscriptions
2284        self.upsert_thread_subscriptions(initial_subscriptions.clone()).await?;
2285
2286        // Assert the subscriptions have been added
2287        for (room_id, thread_id, expected_sub) in &initial_subscriptions {
2288            let stored_subscription = self.load_thread_subscription(room_id, thread_id).await?;
2289            assert_eq!(stored_subscription, Some(*expected_sub));
2290        }
2291
2292        // Update subscriptions
2293        self.upsert_thread_subscriptions(update_subscriptions).await?;
2294
2295        // Assert the expected subscriptions and bump_stamps
2296        for (room_id, thread_id, expected_sub) in &expected_subscriptions {
2297            let stored_subscription = self.load_thread_subscription(room_id, thread_id).await?;
2298            assert_eq!(stored_subscription, Some(*expected_sub));
2299        }
2300
2301        // Test just state changes, but first remove previous subscriptions
2302        for (room_id, thread_id, _) in &expected_subscriptions {
2303            self.remove_thread_subscription(room_id, thread_id).await?;
2304        }
2305
2306        let initial_subscriptions = build_subscription_updates(&[
2307            StoredThreadSubscription {
2308                status: ThreadSubscriptionStatus::Unsubscribed,
2309                bump_stamp: Some(1),
2310            },
2311            StoredThreadSubscription {
2312                status: ThreadSubscriptionStatus::Subscribed { automatic: false },
2313                bump_stamp: Some(1),
2314            },
2315            StoredThreadSubscription {
2316                status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2317                bump_stamp: Some(1),
2318            },
2319        ]);
2320
2321        self.upsert_thread_subscriptions(initial_subscriptions.clone()).await?;
2322
2323        for (room_id, thread_id, expected_sub) in &initial_subscriptions {
2324            let stored_subscription = self.load_thread_subscription(room_id, thread_id).await?;
2325            assert_eq!(stored_subscription, Some(*expected_sub));
2326        }
2327
2328        let update_subscriptions = build_subscription_updates(&[
2329            StoredThreadSubscription {
2330                status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2331                bump_stamp: Some(2),
2332            },
2333            StoredThreadSubscription {
2334                status: ThreadSubscriptionStatus::Unsubscribed,
2335                bump_stamp: Some(2),
2336            },
2337            StoredThreadSubscription {
2338                status: ThreadSubscriptionStatus::Subscribed { automatic: false },
2339                bump_stamp: Some(2),
2340            },
2341        ]);
2342
2343        self.upsert_thread_subscriptions(update_subscriptions.clone()).await?;
2344
2345        for (room_id, thread_id, expected_sub) in &update_subscriptions {
2346            let stored_subscription = self.load_thread_subscription(room_id, thread_id).await?;
2347            assert_eq!(stored_subscription, Some(*expected_sub));
2348        }
2349
2350        Ok(())
2351    }
2352
2353    async fn test_global_profiles_saving(&self) -> TestResult {
2354        let user_id = user_id();
2355
2356        assert_matches!(self.get_global_profile(user_id).await, Ok(None));
2357
2358        let mut changes = UserProfileChanges::new();
2359        changes.updated.insert(ProfileFieldName::DisplayName, json!("Alice"));
2360        changes.removed.push(ProfileFieldName::AvatarUrl);
2361        let update = UserProfileUpdate::Updated(changes);
2362
2363        let mut changes = StateChanges::default();
2364        changes.global_profiles.insert(user_id.to_owned(), update);
2365        self.save_changes(&changes).await?;
2366
2367        let loaded = self.get_global_profile(user_id).await?.expect("Profile should be saved");
2368        let loaded_map: BTreeMap<String, serde_json::Value> = loaded.into_iter().collect();
2369        assert_eq!(loaded_map.get("displayname"), Some(&json!("Alice")));
2370        assert!(!loaded_map.contains_key("avatar_url"));
2371
2372        let mut changes = UserProfileChanges::new();
2373        changes.removed.push(ProfileFieldName::DisplayName);
2374        changes.updated.insert(ProfileFieldName::AvatarUrl, json!("mxc://example.com/avatar"));
2375        let update2 = UserProfileUpdate::Updated(changes);
2376
2377        let mut changes = StateChanges::default();
2378        changes.global_profiles.insert(user_id.to_owned(), update2);
2379        self.save_changes(&changes).await?;
2380
2381        let loaded2 = self.get_global_profile(user_id).await?.expect("Profile should exist");
2382        let loaded_map2: BTreeMap<String, serde_json::Value> = loaded2.into_iter().collect();
2383        assert!(!loaded_map2.contains_key("displayname"));
2384        assert_eq!(loaded_map2.get("avatar_url"), Some(&json!("mxc://example.com/avatar")));
2385
2386        Ok(())
2387    }
2388
2389    async fn test_global_profiles_bulk_loading(&self) -> TestResult {
2390        let alice = user_id!("@alice:localhost");
2391        let bob = user_id!("@bob:localhost");
2392        let unknown = user_id!("@unknown:localhost");
2393
2394        let mut changes = StateChanges::default();
2395        changes.global_profiles.insert(alice.to_owned(), {
2396            let mut profile_changes = UserProfileChanges::new();
2397            profile_changes.updated.insert(ProfileFieldName::DisplayName, json!("Alice"));
2398            UserProfileUpdate::Updated(profile_changes)
2399        });
2400        changes.global_profiles.insert(bob.to_owned(), {
2401            let mut profile_changes = UserProfileChanges::new();
2402            profile_changes.updated.insert(ProfileFieldName::DisplayName, json!("Bob"));
2403            UserProfileUpdate::Updated(profile_changes)
2404        });
2405        self.save_changes(&changes).await?;
2406
2407        // The bulk getter returns the stored profiles and omits unknown users.
2408        let requested = [alice.to_owned(), bob.to_owned(), unknown.to_owned()];
2409        let profiles = self.get_global_profiles(&requested).await?;
2410
2411        assert_eq!(profiles.len(), 2);
2412        assert!(!profiles.contains_key(unknown));
2413
2414        let alice_map: BTreeMap<String, serde_json::Value> = profiles
2415            .get(alice)
2416            .expect("Alice's profile should be loaded")
2417            .clone()
2418            .into_iter()
2419            .collect();
2420        assert_eq!(alice_map.get("displayname"), Some(&json!("Alice")));
2421
2422        let bob_map: BTreeMap<String, serde_json::Value> = profiles
2423            .get(bob)
2424            .expect("Bob's profile should be loaded")
2425            .clone()
2426            .into_iter()
2427            .collect();
2428        assert_eq!(bob_map.get("displayname"), Some(&json!("Bob")));
2429
2430        Ok(())
2431    }
2432
2433    async fn test_missing_global_profiles(&self) -> TestResult {
2434        // Given four users without any stored global profiles.
2435        let alice = user_id!("@alice:localhost");
2436        let bob = user_id!("@bob:localhost");
2437        let carol = user_id!("@carol:localhost");
2438        let dan = user_id!("@dan:localhost");
2439        let requested = [dan, carol, bob, alice].map(ToOwned::to_owned);
2440        assert_eq!(
2441            self.get_missing_global_profiles(&requested).await?,
2442            vec![dan, carol, bob, alice]
2443        );
2444
2445        // When Alice's profile is stored with Bob's marked as unavailable, and
2446        // Carol's is marked as unavailable later on.
2447        let mut changes = StateChanges::default();
2448        changes.global_profiles.insert(alice.to_owned(), {
2449            let mut profile_changes = UserProfileChanges::new();
2450            profile_changes.updated.insert(ProfileFieldName::DisplayName, json!("Alice"));
2451            UserProfileUpdate::Updated(profile_changes)
2452        });
2453        changes
2454            .unavailable_global_profiles
2455            .insert(bob.to_owned(), MilliSecondsSinceUnixEpoch(uint!(1000)));
2456        self.save_changes(&changes).await?;
2457
2458        let mut changes = StateChanges::default();
2459        changes
2460            .unavailable_global_profiles
2461            .insert(carol.to_owned(), MilliSecondsSinceUnixEpoch(uint!(2000)));
2462        self.save_changes(&changes).await?;
2463
2464        // Then only Dan's profile is missing.
2465        assert_eq!(self.get_missing_global_profiles(&requested).await?, vec![dan]);
2466
2467        // When Bob's profile is received, and then dropped at a later date.
2468        let mut changes = StateChanges::default();
2469        changes.global_profiles.insert(bob.to_owned(), {
2470            let mut profile_changes = UserProfileChanges::new();
2471            profile_changes.updated.insert(ProfileFieldName::DisplayName, json!("Bob"));
2472            UserProfileUpdate::Updated(profile_changes)
2473        });
2474        self.save_changes(&changes).await?;
2475
2476        let mut changes = StateChanges::default();
2477        changes.global_profiles.insert(bob.to_owned(), UserProfileUpdate::Dropped);
2478        self.save_changes(&changes).await?;
2479
2480        // Then Bob's profile is missing again, as it's no longer marked as
2481        // unavailable.
2482        assert_eq!(self.get_missing_global_profiles(&requested).await?, vec![dan, bob]);
2483
2484        Ok(())
2485    }
2486}
2487
2488/// Macro building to allow your StateStore implementation to run the entire
2489/// tests suite locally.
2490///
2491/// You need to provide a `async fn get_store() -> StoreResult<impl StateStore>`
2492/// providing a fresh store on the same level you invoke the macro.
2493///
2494/// ## Usage example
2495///
2496/// ```no_run
2497/// # use matrix_sdk_base::store::{
2498/// #    StateStore,
2499/// #    MemoryStore as MyStore,
2500/// #    Result as StoreResult,
2501/// # };
2502///
2503/// #[cfg(test)]
2504/// mod tests {
2505///     use super::{MyStore, StateStore, StoreResult};
2506///
2507///     async fn get_store() -> StoreResult<impl StateStore> {
2508///         Ok(MyStore::new())
2509///     }
2510///
2511///     statestore_integration_tests!();
2512/// }
2513/// ```
2514#[allow(unused_macros, unused_extern_crates)]
2515#[macro_export]
2516macro_rules! statestore_integration_tests {
2517    () => {
2518        mod statestore_integration_tests {
2519            use matrix_sdk_test::{TestResult, async_test};
2520            use $crate::store::{IntoStateStore, StateStoreIntegrationTests};
2521
2522            use super::get_store;
2523
2524            #[async_test]
2525            async fn test_topic_redaction() -> TestResult {
2526                let store = get_store().await?.into_state_store();
2527                store.test_topic_redaction().await
2528            }
2529
2530            #[async_test]
2531            async fn test_populate_store() -> TestResult {
2532                let store = get_store().await?.into_state_store();
2533                store.test_populate_store().await
2534            }
2535
2536            #[async_test]
2537            async fn test_member_saving() -> TestResult {
2538                let store = get_store().await?.into_state_store();
2539                store.test_member_saving().await
2540            }
2541
2542            #[async_test]
2543            async fn test_filter_saving() -> TestResult {
2544                let store = get_store().await?.into_state_store();
2545                store.test_filter_saving().await
2546            }
2547
2548            #[async_test]
2549            async fn test_user_avatar_url_saving() -> TestResult {
2550                let store = get_store().await?.into_state_store();
2551                store.test_user_avatar_url_saving().await
2552            }
2553
2554            #[async_test]
2555            async fn test_supported_versions_saving() -> TestResult {
2556                let store = get_store().await?.into_state_store();
2557                store.test_supported_versions_saving().await
2558            }
2559
2560            #[async_test]
2561            async fn test_well_known_saving() -> TestResult {
2562                let store = get_store().await?.into_state_store();
2563                store.test_well_known_saving().await
2564            }
2565
2566            #[async_test]
2567            async fn test_sync_token_saving() -> TestResult {
2568                let store = get_store().await?.into_state_store();
2569                store.test_sync_token_saving().await
2570            }
2571
2572            #[async_test]
2573            async fn test_utd_hook_manager_data_saving() -> TestResult {
2574                let store = get_store().await?.into_state_store();
2575                store.test_utd_hook_manager_data_saving().await
2576            }
2577
2578            #[async_test]
2579            async fn test_one_time_key_already_uploaded_data_saving() -> TestResult {
2580                let store = get_store().await?.into_state_store();
2581                store.test_one_time_key_already_uploaded_data_saving().await
2582            }
2583
2584            #[async_test]
2585            async fn test_stripped_member_saving() -> TestResult {
2586                let store = get_store().await?.into_state_store();
2587                store.test_stripped_member_saving().await
2588            }
2589
2590            #[async_test]
2591            async fn test_power_level_saving() -> TestResult {
2592                let store = get_store().await?.into_state_store();
2593                store.test_power_level_saving().await
2594            }
2595
2596            #[async_test]
2597            async fn test_receipts_saving() -> TestResult {
2598                let store = get_store().await?.into_state_store();
2599                store.test_receipts_saving().await
2600            }
2601
2602            #[async_test]
2603            async fn test_custom_storage() -> TestResult {
2604                let store = get_store().await?.into_state_store();
2605                store.test_custom_storage().await
2606            }
2607
2608            #[async_test]
2609            async fn test_stripped_non_stripped() -> TestResult {
2610                let store = get_store().await?.into_state_store();
2611                store.test_stripped_non_stripped().await
2612            }
2613
2614            #[async_test]
2615            async fn test_stripped_state_is_kept_across_saves() -> TestResult {
2616                let store = get_store().await?.into_state_store();
2617                store.test_stripped_state_is_kept_across_saves().await
2618            }
2619
2620            #[async_test]
2621            async fn test_room_info_only_save_keeps_room_data() -> TestResult {
2622                let store = get_store().await?.into_state_store();
2623                store.test_room_info_only_save_keeps_room_data().await
2624            }
2625
2626            #[async_test]
2627            async fn test_room_removal() -> TestResult {
2628                let store = get_store().await?.into_state_store();
2629                store.test_room_removal().await
2630            }
2631
2632            #[async_test]
2633            async fn test_profile_removal() -> TestResult {
2634                let store = get_store().await?.into_state_store();
2635                store.test_profile_removal().await
2636            }
2637
2638            #[async_test]
2639            async fn test_presence_saving() -> TestResult {
2640                let store = get_store().await?.into_state_store();
2641                store.test_presence_saving().await
2642            }
2643
2644            #[async_test]
2645            async fn test_display_names_saving() -> TestResult {
2646                let store = get_store().await?.into_state_store();
2647                store.test_display_names_saving().await
2648            }
2649
2650            #[async_test]
2651            async fn test_send_queue() -> TestResult {
2652                let store = get_store().await?.into_state_store();
2653                store.test_send_queue().await
2654            }
2655
2656            #[async_test]
2657            async fn test_send_queue_priority() -> TestResult {
2658                let store = get_store().await?.into_state_store();
2659                store.test_send_queue_priority().await
2660            }
2661
2662            #[async_test]
2663            async fn test_send_queue_dependents() -> TestResult {
2664                let store = get_store().await?.into_state_store();
2665                store.test_send_queue_dependents().await
2666            }
2667
2668            #[async_test]
2669            async fn test_send_queue_sticky_events() -> TestResult {
2670                let store = get_store().await?.into_state_store();
2671                store.test_send_queue_sticky_events().await
2672            }
2673
2674            #[async_test]
2675            async fn test_update_send_queue_dependent() -> TestResult {
2676                let store = get_store().await?.into_state_store();
2677                store.test_update_send_queue_dependent().await
2678            }
2679
2680            #[async_test]
2681            async fn test_get_room_infos() -> TestResult {
2682                let store = get_store().await?.into_state_store();
2683                store.test_get_room_infos().await
2684            }
2685
2686            #[async_test]
2687            async fn test_thread_subscriptions() -> TestResult {
2688                let store = get_store().await?.into_state_store();
2689                store.test_thread_subscriptions().await
2690            }
2691
2692            #[async_test]
2693            async fn test_thread_subscriptions_bulk_upsert() -> TestResult {
2694                let store = get_store().await?.into_state_store();
2695                store.test_thread_subscriptions_bulk_upsert().await
2696            }
2697
2698            #[async_test]
2699            async fn test_global_profiles_saving() -> TestResult {
2700                let store = get_store().await?.into_state_store();
2701                store.test_global_profiles_saving().await
2702            }
2703
2704            #[async_test]
2705            async fn test_global_profiles_bulk_loading() -> TestResult {
2706                let store = get_store().await?.into_state_store();
2707                store.test_global_profiles_bulk_loading().await
2708            }
2709
2710            #[async_test]
2711            async fn test_missing_global_profiles() -> TestResult {
2712                let store = get_store().await?.into_state_store();
2713                store.test_missing_global_profiles().await
2714            }
2715        }
2716    };
2717}
2718
2719fn user_id() -> &'static UserId {
2720    user_id!("@example:localhost")
2721}
2722
2723fn invited_user_id() -> &'static UserId {
2724    user_id!("@invited:localhost")
2725}
2726
2727fn room_id() -> &'static RoomId {
2728    room_id!("!test:localhost")
2729}
2730
2731fn stripped_room_id() -> &'static RoomId {
2732    room_id!("!stripped:localhost")
2733}
2734
2735fn first_receipt_event_id() -> &'static EventId {
2736    event_id!("$example")
2737}
2738
2739fn topic_event_id() -> &'static EventId {
2740    event_id!("$topic_event")
2741}
2742
2743fn power_level_event() -> Raw<AnySyncStateEvent> {
2744    let content = RoomPowerLevelsEventContent::new(&AuthorizationRules::V1);
2745
2746    let event = json!({
2747        "event_id": "$h29iv0s8:example.com",
2748        "content": content,
2749        "sender": user_id(),
2750        "type": "m.room.power_levels",
2751        "origin_server_ts": 0u64,
2752        "state_key": "",
2753    });
2754
2755    serde_json::from_value(event).unwrap()
2756}
2757
2758fn stripped_membership_event() -> Raw<StrippedRoomMemberEvent> {
2759    custom_stripped_membership_event(user_id())
2760}
2761
2762fn custom_stripped_membership_event(user_id: &UserId) -> Raw<StrippedRoomMemberEvent> {
2763    let ev_json = json!({
2764        "type": "m.room.member",
2765        "content": RoomMemberEventContent::new(MembershipState::Join),
2766        "sender": user_id,
2767        "state_key": user_id,
2768    });
2769
2770    Raw::new(&ev_json).unwrap().cast_unchecked()
2771}
2772
2773fn membership_event() -> Raw<SyncRoomMemberEvent> {
2774    custom_membership_event(user_id(), event_id!("$h29iv0s8:example.com"))
2775}
2776
2777fn custom_membership_event(user_id: &UserId, event_id: &EventId) -> Raw<SyncRoomMemberEvent> {
2778    let ev_json = json!({
2779        "type": "m.room.member",
2780        "content": RoomMemberEventContent::new(MembershipState::Join),
2781        "event_id": event_id,
2782        "origin_server_ts": 198,
2783        "sender": user_id,
2784        "state_key": user_id,
2785    });
2786
2787    Raw::new(&ev_json).unwrap().cast_unchecked()
2788}
2789
2790fn custom_presence_event(user_id: &UserId) -> Raw<PresenceEvent> {
2791    let ev_json = json!({
2792        "content": {
2793            "presence": "online"
2794        },
2795        "sender": user_id,
2796    });
2797
2798    Raw::new(&ev_json).unwrap().cast_unchecked()
2799}