matrix_sdk_base/store/
integration_tests.rs

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