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