1use std::{
4 collections::{BTreeMap, BTreeSet, HashMap},
5 str::FromStr,
6};
7
8use assert_matches::assert_matches;
9use assert_matches2::assert_let;
10use growable_bloom_filter::GrowableBloomBuilder;
11use matrix_sdk_common::ttl::TtlValue;
12use matrix_sdk_test::{TestResult, event_factory::EventFactory};
13use ruma::{
14 EventId, MilliSecondsSinceUnixEpoch, OwnedUserId, RoomId, TransactionId, UserId,
15 api::{
16 FeatureFlag, MatrixVersion,
17 client::{discovery::discover_homeserver::HomeserverInfo, rtc::RtcTransport},
18 },
19 event_id,
20 events::{
21 AnyGlobalAccountDataEvent, AnyMessageLikeEventContent, AnyRoomAccountDataEvent,
22 AnyStrippedStateEvent, AnySyncStateEvent, GlobalAccountDataEventType,
23 RoomAccountDataEventType, StateEventType, SyncStateEvent,
24 presence::PresenceEvent,
25 receipt::{ReceiptThread, ReceiptType},
26 room::{
27 member::{
28 MembershipState, RoomMemberEventContent, StrippedRoomMemberEvent,
29 SyncRoomMemberEvent,
30 },
31 message::RoomMessageEventContent,
32 power_levels::RoomPowerLevelsEventContent,
33 redaction::SyncRoomRedactionEvent,
34 topic::RoomTopicEventContent,
35 },
36 tag::{TagInfo, TagName, Tags, UserTagName},
37 },
38 mxc_uri, owned_event_id, owned_mxc_uri,
39 presence::PresenceState,
40 profile::UserProfileUpdate,
41 push::Ruleset,
42 room_id,
43 room_version_rules::AuthorizationRules,
44 serde::Raw,
45 uint, user_id,
46};
47use serde_json::json;
48
49use super::{
50 DependentQueuedRequestKind, DisplayName, DynStateStore, RoomLoadSettings,
51 SupportedVersionsResponse, WellKnownResponse, send_queue::SentRequestKey,
52};
53use crate::{
54 RoomInfo, RoomMemberships, RoomState, StateChanges, StateStoreDataKey, StateStoreDataValue,
55 deserialized_responses::MemberEvent,
56 store::{
57 ChildTransactionId, QueueWedgeError, SerializableEventContent, StateStoreExt,
58 StoredThreadSubscription, ThreadSubscriptionStatus,
59 },
60 utils::RawStateEventWithKeys,
61};
62
63#[allow(async_fn_in_trait)]
68pub trait StateStoreIntegrationTests {
69 async fn populate(&self) -> TestResult;
71 async fn test_topic_redaction(&self) -> TestResult;
73 async fn test_populate_store(&self) -> TestResult;
75 async fn test_member_saving(&self) -> TestResult;
77 async fn test_filter_saving(&self) -> TestResult;
79 async fn test_user_avatar_url_saving(&self) -> TestResult;
81 async fn test_sync_token_saving(&self) -> TestResult;
83 async fn test_utd_hook_manager_data_saving(&self) -> TestResult;
85 async fn test_one_time_key_already_uploaded_data_saving(&self) -> TestResult;
87 async fn test_stripped_member_saving(&self) -> TestResult;
89 async fn test_power_level_saving(&self) -> TestResult;
91 async fn test_receipts_saving(&self) -> TestResult;
93 async fn test_custom_storage(&self) -> TestResult;
95 async fn test_stripped_non_stripped(&self) -> TestResult;
97 async fn test_room_removal(&self) -> TestResult;
99 async fn test_profile_removal(&self) -> TestResult;
101 async fn test_presence_saving(&self) -> TestResult;
103 async fn test_display_names_saving(&self) -> TestResult;
105 async fn test_send_queue(&self) -> TestResult;
107 async fn test_send_queue_priority(&self) -> TestResult;
109 async fn test_send_queue_dependents(&self) -> TestResult;
111 async fn test_update_send_queue_dependent(&self) -> TestResult;
113 async fn test_supported_versions_saving(&self) -> TestResult;
115 async fn test_well_known_saving(&self) -> TestResult;
117 async fn test_get_room_infos(&self) -> TestResult;
119 async fn test_thread_subscriptions(&self) -> TestResult;
121 async fn test_thread_subscriptions_bulk_upsert(&self) -> TestResult;
123 async fn test_global_profiles_saving(&self) -> TestResult;
125 async fn test_global_profiles_bulk_loading(&self) -> TestResult;
127}
128
129impl StateStoreIntegrationTests for DynStateStore {
130 async fn populate(&self) -> TestResult {
131 let mut changes = StateChanges::default();
132
133 let user_id = user_id();
134 let invited_user_id = invited_user_id();
135 let room_id = room_id();
136 let stripped_room_id = stripped_room_id();
137
138 changes.sync_token = Some("t392-516_47314_0_7_1_1_1_11444_1".to_owned());
139
140 let f = EventFactory::new().sender(user_id);
141 let presence_raw: Raw<PresenceEvent> = f
142 .presence(PresenceState::Online)
143 .avatar_url(mxc_uri!("mxc://localhost/wefuiwegh8742w"))
144 .currently_active(false)
145 .last_active_ago(1)
146 .status_msg("Making cupcakes")
147 .into();
148 let presence_event = presence_raw.deserialize()?;
149 changes.add_presence_event(presence_event, presence_raw);
150
151 let f = EventFactory::new().sender(user_id);
152 let pushrules_raw: Raw<AnyGlobalAccountDataEvent> =
153 f.push_rules(Ruleset::server_default(user_id)).into();
154 let pushrules_event = pushrules_raw.deserialize()?;
155 changes.account_data.insert(pushrules_event.event_type(), pushrules_raw);
156
157 let mut room = RoomInfo::new(room_id, RoomState::Joined);
158 room.mark_as_left();
159
160 let f = EventFactory::new().sender(user_id).room(room_id);
161 let mut tags = Tags::new();
162 tags.insert(TagName::Favorite, TagInfo::new());
163 tags.insert(TagName::User(UserTagName::from_str("u.work").unwrap()), TagInfo::new());
164 let tag_raw: Raw<AnyRoomAccountDataEvent> = f.tag(tags).into();
165 let tag_event = tag_raw.deserialize()?;
166 changes.add_room_account_data(room_id, tag_event, tag_raw);
167
168 let f = EventFactory::new().sender(user_id).room(room_id);
169 let name_raw: Raw<AnySyncStateEvent> = f.room_name("room name").into();
170 let name_event = name_raw.deserialize()?;
171 room.handle_state_event(
172 &mut RawStateEventWithKeys::try_from_raw_state_event(name_raw.clone())
173 .expect("generated state event should be valid"),
174 );
175 changes.add_state_event(room_id, name_event, name_raw);
176
177 let f = EventFactory::new().sender(user_id);
178 let receipt_content = f
179 .room(room_id)
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 let topic_event_id = topic_event_id();
186 let topic_raw: Raw<AnySyncStateEvent> = EventFactory::new()
187 .room(room_id)
188 .sender(user_id)
189 .room_topic("😀")
190 .event_id(topic_event_id)
191 .prev_content(RoomTopicEventContent::new("test".to_owned()))
192 .into_raw_sync_state();
193 let topic_event = topic_raw.deserialize()?;
194 room.handle_state_event(
195 &mut RawStateEventWithKeys::try_from_raw_state_event(topic_raw.clone())
196 .expect("generated state event should be valid"),
197 );
198 changes.add_state_event(room_id, topic_event, topic_raw);
199
200 let mut room_ambiguity_map = HashMap::new();
201 let mut room_profiles = BTreeMap::new();
202
203 let f = EventFactory::new().sender(user_id).room(room_id);
204 let member_raw: Raw<SyncRoomMemberEvent> =
205 f.member(user_id).display_name("example").previous(MembershipState::Invite).into();
206 let member_event: SyncRoomMemberEvent = member_raw.deserialize()?;
207 let displayname = DisplayName::new(
208 member_event.as_original().unwrap().content.displayname.as_ref().unwrap(),
209 );
210 room_ambiguity_map.insert(displayname.clone(), BTreeSet::from([user_id.to_owned()]));
211 room_profiles.insert(user_id.to_owned(), (&member_event).into());
212
213 let member_raw: Raw<AnySyncStateEvent> = member_raw.cast_unchecked();
214 let member_state_event = member_raw.deserialize()?;
215 changes.add_state_event(room_id, member_state_event, member_raw);
216
217 let f = EventFactory::new().sender(user_id).room(room_id);
218 let invited_member_raw: Raw<SyncRoomMemberEvent> = f
219 .member(invited_user_id)
220 .invited(invited_user_id)
221 .display_name("example")
222 .avatar_url(mxc_uri!("mxc://localhost/SEsfnsuifSDFSSEF"))
223 .reason("Looking for support")
224 .into();
225 let invited_member_event: SyncRoomMemberEvent = invited_member_raw.deserialize()?;
227 room_ambiguity_map.entry(displayname).or_default().insert(invited_user_id.to_owned());
228 room_profiles.insert(invited_user_id.to_owned(), (&invited_member_event).into());
229
230 let invited_member_raw: Raw<AnySyncStateEvent> = invited_member_raw.cast_unchecked();
231 let invited_member_state_event = invited_member_raw.deserialize()?;
232 changes.add_state_event(room_id, invited_member_state_event, invited_member_raw);
233
234 changes.ambiguity_maps.insert(room_id.to_owned(), room_ambiguity_map);
235 changes.profiles.insert(room_id.to_owned(), room_profiles);
236 changes.add_room(room);
237
238 let mut stripped_room = RoomInfo::new(stripped_room_id, RoomState::Invited);
239
240 let f = EventFactory::new().sender(user_id).room(stripped_room_id);
241 let stripped_name_raw: Raw<AnyStrippedStateEvent> = f.room_name("room name").into();
242 let mut stripped_name_event =
243 RawStateEventWithKeys::try_from_raw_state_event(stripped_name_raw).unwrap();
244 stripped_room.handle_stripped_state_event(&mut stripped_name_event);
245 changes.stripped_state.insert(
246 stripped_room_id.to_owned(),
247 BTreeMap::from([(
248 stripped_name_event.event_type,
249 BTreeMap::from([(stripped_name_event.state_key, stripped_name_event.raw)]),
250 )]),
251 );
252
253 changes.add_room(stripped_room);
254
255 let f = EventFactory::new().sender(user_id).room(stripped_room_id);
256 let stripped_member_raw: Raw<StrippedRoomMemberEvent> =
257 f.member(user_id).display_name("example").into();
258 changes.add_stripped_member(stripped_room_id, user_id, stripped_member_raw);
259
260 self.save_changes(&changes).await?;
261
262 Ok(())
263 }
264
265 async fn test_topic_redaction(&self) -> TestResult {
266 let room_id = room_id();
267 let f = EventFactory::new();
268 self.populate().await?;
269
270 assert!(self.get_kv_data(StateStoreDataKey::SyncToken).await?.is_some());
271 assert_eq!(
272 self.get_state_event_static::<RoomTopicEventContent>(room_id)
273 .await?
274 .expect("room topic found before redaction")
275 .deserialize()
276 .expect("can deserialize room topic before redaction")
277 .as_sync()
278 .expect("room topic is a sync state event")
279 .as_original()
280 .expect("room topic is not redacted yet")
281 .content
282 .topic,
283 "😀"
284 );
285
286 let mut changes = StateChanges::default();
287
288 let topic_event_id = topic_event_id();
289 let redaction_evt: Raw<SyncRoomRedactionEvent> =
290 f.room(room_id).sender(user_id()).redaction(topic_event_id).into_raw();
291
292 changes.add_redaction(room_id, topic_event_id, redaction_evt);
293 self.save_changes(&changes).await?;
294
295 let redacted_event = self
296 .get_state_event_static::<RoomTopicEventContent>(room_id)
297 .await?
298 .expect("room topic found after redaction")
299 .deserialize()
300 .expect("can deserialize room topic after redaction");
301
302 assert_matches!(redacted_event.as_sync(), Some(SyncStateEvent::Redacted(_)));
303
304 Ok(())
305 }
306
307 async fn test_populate_store(&self) -> TestResult {
308 let room_id = room_id();
309 let user_id = user_id();
310 let display_name = DisplayName::new("example");
311
312 self.populate().await?;
313
314 assert!(self.get_kv_data(StateStoreDataKey::SyncToken).await?.is_some());
315 assert!(self.get_presence_event(user_id).await?.is_some());
316 assert_eq!(
317 self.get_room_infos(&RoomLoadSettings::default()).await?.len(),
318 2,
319 "Expected to find 2 room infos"
320 );
321 assert!(
322 self.get_account_data_event(GlobalAccountDataEventType::PushRules).await?.is_some()
323 );
324
325 assert!(self.get_state_event(room_id, StateEventType::RoomName, "").await?.is_some());
326 assert_eq!(
327 self.get_state_events(room_id, StateEventType::RoomTopic).await?.len(),
328 1,
329 "Expected to find 1 room topic"
330 );
331 assert!(self.get_profile(room_id, user_id).await?.is_some());
332 assert!(self.get_member_event(room_id, user_id).await?.is_some());
333 assert_eq!(
334 self.get_user_ids(room_id, RoomMemberships::empty()).await?.len(),
335 2,
336 "Expected to find 2 members for room"
337 );
338 assert_eq!(
339 self.get_user_ids(room_id, RoomMemberships::INVITE).await?.len(),
340 1,
341 "Expected to find 1 invited user ids"
342 );
343 assert_eq!(
344 self.get_user_ids(room_id, RoomMemberships::JOIN).await?.len(),
345 1,
346 "Expected to find 1 joined user ids"
347 );
348 assert_eq!(
349 self.get_users_with_display_name(room_id, &display_name).await?.len(),
350 2,
351 "Expected to find 2 display names for room"
352 );
353 assert!(
354 self.get_room_account_data_event(room_id, RoomAccountDataEventType::Tag)
355 .await?
356 .is_some()
357 );
358 assert!(
359 self.get_user_room_receipt_event(
360 room_id,
361 ReceiptType::Read,
362 ReceiptThread::Unthreaded,
363 user_id
364 )
365 .await?
366 .is_some()
367 );
368 assert_eq!(
369 self.get_event_room_receipt_events(
370 room_id,
371 ReceiptType::Read,
372 ReceiptThread::Unthreaded,
373 first_receipt_event_id()
374 )
375 .await?
376 .len(),
377 1,
378 "Expected to find 1 read receipt"
379 );
380 Ok(())
381 }
382
383 async fn test_member_saving(&self) -> TestResult {
384 let room_id = room_id!("!test_member_saving:localhost");
385 let user_id = user_id();
386 let second_user_id = user_id!("@second:localhost");
387 let third_user_id = user_id!("@third:localhost");
388 let unknown_user_id = user_id!("@unknown:localhost");
389
390 let mut user_ids = vec![user_id.to_owned()];
392 assert!(self.get_member_event(room_id, user_id).await?.is_none());
393 let member_events = self
394 .get_state_events_for_keys_static::<RoomMemberEventContent, _, _>(room_id, &user_ids)
395 .await;
396 assert!(member_events?.is_empty());
397 assert!(self.get_profile(room_id, user_id).await?.is_none());
398 let profiles = self.get_profiles(room_id, &user_ids).await;
399 assert!(profiles?.is_empty());
400
401 let mut changes = StateChanges::default();
403 let raw_member_event = membership_event();
404 let profile = raw_member_event.deserialize()?.into();
405 changes
406 .state
407 .entry(room_id.to_owned())
408 .or_default()
409 .entry(StateEventType::RoomMember)
410 .or_default()
411 .insert(user_id.into(), raw_member_event.cast());
412 changes.profiles.entry(room_id.to_owned()).or_default().insert(user_id.to_owned(), profile);
413 self.save_changes(&changes).await?;
414
415 assert!(self.get_member_event(room_id, user_id).await?.is_some());
416 let member_events = self
417 .get_state_events_for_keys_static::<RoomMemberEventContent, _, _>(room_id, &user_ids)
418 .await;
419 assert_eq!(member_events?.len(), 1);
420 let members = self.get_user_ids(room_id, RoomMemberships::empty()).await?;
421 assert_eq!(members.len(), 1, "We expected to find members for the room");
422 assert!(self.get_profile(room_id, user_id).await?.is_some());
423 let profiles = self.get_profiles(room_id, &user_ids).await;
424 assert_eq!(profiles?.len(), 1);
425
426 let mut changes = StateChanges::default();
428 let changes_members = changes
429 .state
430 .entry(room_id.to_owned())
431 .or_default()
432 .entry(StateEventType::RoomMember)
433 .or_default();
434 let changes_profiles = changes.profiles.entry(room_id.to_owned()).or_default();
435 let raw_second_member_event =
436 custom_membership_event(second_user_id, event_id!("$second_member_event"));
437 let second_profile = raw_second_member_event.deserialize()?.into();
438 changes_members.insert(second_user_id.into(), raw_second_member_event.cast());
439 changes_profiles.insert(second_user_id.to_owned(), second_profile);
440 let raw_third_member_event =
441 custom_membership_event(third_user_id, event_id!("$third_member_event"));
442 let third_profile = raw_third_member_event.deserialize()?.into();
443 changes_members.insert(third_user_id.into(), raw_third_member_event.cast());
444 changes_profiles.insert(third_user_id.to_owned(), third_profile);
445 self.save_changes(&changes).await?;
446
447 user_ids.extend([second_user_id.to_owned(), third_user_id.to_owned()]);
448 assert!(self.get_member_event(room_id, second_user_id).await?.is_some());
449 assert!(self.get_member_event(room_id, third_user_id).await?.is_some());
450 let member_events = self
451 .get_state_events_for_keys_static::<RoomMemberEventContent, _, _>(room_id, &user_ids)
452 .await;
453 assert_eq!(member_events?.len(), 3);
454 let members = self.get_user_ids(room_id, RoomMemberships::empty()).await?;
455 assert_eq!(members.len(), 3, "We expected to find members for the room");
456 assert!(self.get_profile(room_id, second_user_id).await?.is_some());
457 assert!(self.get_profile(room_id, third_user_id).await?.is_some());
458 let profiles = self.get_profiles(room_id, &user_ids).await;
459 assert_eq!(profiles?.len(), 3);
460
461 user_ids.push(unknown_user_id.to_owned());
463 let member_events = self
464 .get_state_events_for_keys_static::<RoomMemberEventContent, _, _>(room_id, &user_ids)
465 .await;
466 assert_eq!(member_events?.len(), 3);
467 let profiles = self.get_profiles(room_id, &user_ids).await;
468 assert_eq!(profiles?.len(), 3);
469
470 let member_events = self
472 .get_state_events_for_keys_static::<RoomMemberEventContent, OwnedUserId, _>(
473 room_id,
474 &[],
475 )
476 .await;
477 assert!(member_events?.is_empty());
478 let profiles = self.get_profiles(room_id, &[]).await;
479 assert!(profiles?.is_empty());
480
481 Ok(())
482 }
483
484 async fn test_filter_saving(&self) -> TestResult {
485 let filter_name = "filter_name";
486 let filter_id = "filter_id_1234";
487
488 self.set_kv_data(
489 StateStoreDataKey::Filter(filter_name),
490 StateStoreDataValue::Filter(filter_id.to_owned()),
491 )
492 .await?;
493 assert_let!(
494 Ok(Some(StateStoreDataValue::Filter(stored_filter_id))) =
495 self.get_kv_data(StateStoreDataKey::Filter(filter_name)).await
496 );
497 assert_eq!(stored_filter_id, filter_id);
498
499 self.remove_kv_data(StateStoreDataKey::Filter(filter_name)).await?;
500 assert_matches!(self.get_kv_data(StateStoreDataKey::Filter(filter_name)).await, Ok(None));
501
502 Ok(())
503 }
504
505 async fn test_user_avatar_url_saving(&self) -> TestResult {
506 let user_id = user_id!("@alice:example.org");
507 let url = owned_mxc_uri!("mxc://example.org/poiuyt098");
508
509 self.set_kv_data(
510 StateStoreDataKey::UserAvatarUrl(user_id),
511 StateStoreDataValue::UserAvatarUrl(url.clone()),
512 )
513 .await?;
514
515 assert_let!(
516 Ok(Some(StateStoreDataValue::UserAvatarUrl(stored_url))) =
517 self.get_kv_data(StateStoreDataKey::UserAvatarUrl(user_id)).await
518 );
519 assert_eq!(stored_url, url);
520
521 self.remove_kv_data(StateStoreDataKey::UserAvatarUrl(user_id)).await?;
522 assert_matches!(
523 self.get_kv_data(StateStoreDataKey::UserAvatarUrl(user_id)).await,
524 Ok(None)
525 );
526
527 Ok(())
528 }
529
530 async fn test_supported_versions_saving(&self) -> TestResult {
531 let versions =
532 BTreeSet::from([MatrixVersion::V1_1, MatrixVersion::V1_2, MatrixVersion::V1_11]);
533 let supported_versions = SupportedVersionsResponse {
534 versions: versions.iter().map(|version| version.as_str().unwrap().to_owned()).collect(),
535 unstable_features: [("org.matrix.experimental".to_owned(), true)].into(),
536 };
537
538 self.set_kv_data(
539 StateStoreDataKey::SupportedVersions,
540 StateStoreDataValue::SupportedVersions(TtlValue::new(supported_versions.clone())),
541 )
542 .await?;
543
544 assert_let!(
545 Ok(Some(StateStoreDataValue::SupportedVersions(stored_supported_versions))) =
546 self.get_kv_data(StateStoreDataKey::SupportedVersions).await
547 );
548 let stored_supported_versions = stored_supported_versions.into_data();
549 assert_eq!(supported_versions, stored_supported_versions);
550
551 let stored_supported = stored_supported_versions.supported_versions();
552 assert_eq!(stored_supported.versions, versions);
553 assert_eq!(stored_supported.features.len(), 1);
554 assert!(stored_supported.features.contains(&FeatureFlag::from("org.matrix.experimental")));
555
556 self.remove_kv_data(StateStoreDataKey::SupportedVersions).await?;
557 assert_matches!(self.get_kv_data(StateStoreDataKey::SupportedVersions).await, Ok(None));
558
559 Ok(())
560 }
561
562 async fn test_well_known_saving(&self) -> TestResult {
563 let well_known = WellKnownResponse {
564 homeserver: HomeserverInfo::new("matrix.example.com".to_owned()),
565 identity_server: None,
566 tile_server: None,
567 rtc_foci: vec![RtcTransport::livekit("livekit.example.com".to_owned())],
568 };
569
570 self.set_kv_data(
571 StateStoreDataKey::WellKnown,
572 StateStoreDataValue::WellKnown(TtlValue::new(Some(well_known.clone()))),
573 )
574 .await?;
575
576 assert_let!(
577 Ok(Some(StateStoreDataValue::WellKnown(stored_well_known))) =
578 self.get_kv_data(StateStoreDataKey::WellKnown).await
579 );
580 let stored_well_known = stored_well_known.into_data();
581 assert_eq!(stored_well_known, Some(well_known));
582
583 self.remove_kv_data(StateStoreDataKey::WellKnown).await?;
584 assert_matches!(self.get_kv_data(StateStoreDataKey::WellKnown).await, Ok(None));
585
586 self.set_kv_data(
587 StateStoreDataKey::WellKnown,
588 StateStoreDataValue::WellKnown(TtlValue::new(None)),
589 )
590 .await?;
591
592 assert_let!(
593 Ok(Some(StateStoreDataValue::WellKnown(stored_well_known))) =
594 self.get_kv_data(StateStoreDataKey::WellKnown).await
595 );
596 let stored_well_known = stored_well_known.into_data();
597 assert_eq!(stored_well_known, None);
598
599 Ok(())
600 }
601
602 async fn test_sync_token_saving(&self) -> TestResult {
603 let sync_token_1 = "t392-516_47314_0_7_1";
604 let sync_token_2 = "t392-516_47314_0_7_2";
605
606 assert_matches!(self.get_kv_data(StateStoreDataKey::SyncToken).await, Ok(None));
607
608 let changes =
609 StateChanges { sync_token: Some(sync_token_1.to_owned()), ..Default::default() };
610 self.save_changes(&changes).await?;
611 assert_let!(
612 Ok(Some(StateStoreDataValue::SyncToken(stored_sync_token))) =
613 self.get_kv_data(StateStoreDataKey::SyncToken).await
614 );
615 assert_eq!(stored_sync_token, sync_token_1);
616
617 self.set_kv_data(
618 StateStoreDataKey::SyncToken,
619 StateStoreDataValue::SyncToken(sync_token_2.to_owned()),
620 )
621 .await?;
622 assert_let!(
623 Ok(Some(StateStoreDataValue::SyncToken(stored_sync_token))) =
624 self.get_kv_data(StateStoreDataKey::SyncToken).await
625 );
626 assert_eq!(stored_sync_token, sync_token_2);
627
628 self.remove_kv_data(StateStoreDataKey::SyncToken).await?;
629 assert_matches!(self.get_kv_data(StateStoreDataKey::SyncToken).await, Ok(None));
630
631 Ok(())
632 }
633
634 async fn test_utd_hook_manager_data_saving(&self) -> TestResult {
635 assert!(
637 self.get_kv_data(StateStoreDataKey::UtdHookManagerData)
638 .await
639 .expect("Could not read data")
640 .is_none(),
641 "Store was not empty at start"
642 );
643
644 let data = GrowableBloomBuilder::new().build();
646 self.set_kv_data(
647 StateStoreDataKey::UtdHookManagerData,
648 StateStoreDataValue::UtdHookManagerData(data.clone()),
649 )
650 .await
651 .expect("Could not save data");
652
653 let read_data = self
655 .get_kv_data(StateStoreDataKey::UtdHookManagerData)
656 .await
657 .expect("Could not read data")
658 .expect("no data found")
659 .into_utd_hook_manager_data()
660 .expect("not UtdHookManagerData");
661
662 assert_eq!(read_data, data);
663
664 Ok(())
665 }
666
667 async fn test_one_time_key_already_uploaded_data_saving(&self) -> TestResult {
668 assert!(
670 self.get_kv_data(StateStoreDataKey::OneTimeKeyAlreadyUploaded).await?.is_none(),
671 "Store was not empty at start"
672 );
673
674 self.set_kv_data(
675 StateStoreDataKey::OneTimeKeyAlreadyUploaded,
676 StateStoreDataValue::OneTimeKeyAlreadyUploaded,
677 )
678 .await?;
679
680 let data = self.get_kv_data(StateStoreDataKey::OneTimeKeyAlreadyUploaded).await?;
681 data.expect("The loaded data should be Some");
682
683 Ok(())
684 }
685
686 async fn test_stripped_member_saving(&self) -> TestResult {
687 let room_id = room_id!("!test_stripped_member_saving:localhost");
688 let user_id = user_id();
689 let second_user_id = user_id!("@second:localhost");
690 let third_user_id = user_id!("@third:localhost");
691 let unknown_user_id = user_id!("@unknown:localhost");
692
693 assert!(self.get_member_event(room_id, user_id).await?.is_none());
695 let member_events = self
696 .get_state_events_for_keys_static::<RoomMemberEventContent, _, _>(
697 room_id,
698 &[user_id.to_owned()],
699 )
700 .await;
701 assert!(member_events?.is_empty());
702
703 let mut changes = StateChanges::default();
705 changes
706 .stripped_state
707 .entry(room_id.to_owned())
708 .or_default()
709 .entry(StateEventType::RoomMember)
710 .or_default()
711 .insert(user_id.into(), stripped_membership_event().cast());
712 self.save_changes(&changes).await?;
713
714 assert!(self.get_member_event(room_id, user_id).await?.is_some());
715 let member_events = self
716 .get_state_events_for_keys_static::<RoomMemberEventContent, _, _>(
717 room_id,
718 &[user_id.to_owned()],
719 )
720 .await;
721 assert_eq!(member_events?.len(), 1);
722 let members = self.get_user_ids(room_id, RoomMemberships::empty()).await?;
723 assert_eq!(members.len(), 1, "We expected to find members for the room");
724
725 let mut changes = StateChanges::default();
727 let changes_members = changes
728 .stripped_state
729 .entry(room_id.to_owned())
730 .or_default()
731 .entry(StateEventType::RoomMember)
732 .or_default();
733 changes_members
734 .insert(second_user_id.into(), custom_stripped_membership_event(second_user_id).cast());
735 changes_members
736 .insert(third_user_id.into(), custom_stripped_membership_event(third_user_id).cast());
737 self.save_changes(&changes).await?;
738
739 assert!(self.get_member_event(room_id, second_user_id).await?.is_some());
740 assert!(self.get_member_event(room_id, third_user_id).await?.is_some());
741 let member_events = self
742 .get_state_events_for_keys_static::<RoomMemberEventContent, _, _>(
743 room_id,
744 &[user_id.to_owned(), second_user_id.to_owned(), third_user_id.to_owned()],
745 )
746 .await;
747 assert_eq!(member_events?.len(), 3);
748 let members = self.get_user_ids(room_id, RoomMemberships::empty()).await?;
749 assert_eq!(members.len(), 3, "We expected to find members for the room");
750
751 let member_events = self
753 .get_state_events_for_keys_static::<RoomMemberEventContent, _, _>(
754 room_id,
755 &[
756 user_id.to_owned(),
757 second_user_id.to_owned(),
758 third_user_id.to_owned(),
759 unknown_user_id.to_owned(),
760 ],
761 )
762 .await;
763 assert_eq!(member_events?.len(), 3);
764
765 let member_events = self
767 .get_state_events_for_keys_static::<RoomMemberEventContent, OwnedUserId, _>(
768 room_id,
769 &[],
770 )
771 .await;
772 assert!(member_events?.is_empty());
773
774 Ok(())
775 }
776
777 async fn test_power_level_saving(&self) -> TestResult {
778 let room_id = room_id!("!test_power_level_saving:localhost");
779
780 let raw_event = power_level_event();
781 let event = raw_event.deserialize()?;
782
783 assert!(
784 self.get_state_event(room_id, StateEventType::RoomPowerLevels, "").await?.is_none()
785 );
786 let mut changes = StateChanges::default();
787 changes.add_state_event(room_id, event, raw_event);
788
789 self.save_changes(&changes).await?;
790 assert!(
791 self.get_state_event(room_id, StateEventType::RoomPowerLevels, "").await?.is_some()
792 );
793
794 Ok(())
795 }
796
797 async fn test_receipts_saving(&self) -> TestResult {
798 let room_id = room_id!("!test_receipts_saving:localhost");
799
800 let first_event_id = event_id!("$1435641916114394fHBLK:matrix.org");
801 let second_event_id = event_id!("$fHBLK1435641916114394:matrix.org");
802
803 let first_receipt_ts = uint!(1436451550);
804 let second_receipt_ts = uint!(1436451653);
805 let third_receipt_ts = uint!(1436474532);
806
807 let first_receipt_event = serde_json::from_value(json!({
808 first_event_id: {
809 "m.read": {
810 user_id(): {
811 "ts": first_receipt_ts,
812 }
813 }
814 }
815 }))?;
816
817 let second_receipt_event = serde_json::from_value(json!({
818 second_event_id: {
819 "m.read": {
820 user_id(): {
821 "ts": second_receipt_ts,
822 }
823 }
824 }
825 }))?;
826
827 let third_receipt_event = serde_json::from_value(json!({
828 second_event_id: {
829 "m.read": {
830 user_id(): {
831 "ts": third_receipt_ts,
832 "thread_id": "main",
833 }
834 }
835 }
836 }))?;
837
838 assert!(
839 self.get_user_room_receipt_event(
840 room_id,
841 ReceiptType::Read,
842 ReceiptThread::Unthreaded,
843 user_id()
844 )
845 .await
846 .expect("failed to read unthreaded user room receipt")
847 .is_none()
848 );
849 assert!(
850 self.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")
858 .is_empty()
859 );
860 assert!(
861 self.get_event_room_receipt_events(
862 room_id,
863 ReceiptType::Read,
864 ReceiptThread::Unthreaded,
865 second_event_id
866 )
867 .await
868 .expect("failed to read unthreaded event room receipt for 2")
869 .is_empty()
870 );
871
872 let mut changes = StateChanges::default();
873 changes.add_receipts(room_id, first_receipt_event);
874
875 self.save_changes(&changes).await?;
876 let (unthreaded_user_receipt_event_id, unthreaded_user_receipt) = self
877 .get_user_room_receipt_event(
878 room_id,
879 ReceiptType::Read,
880 ReceiptThread::Unthreaded,
881 user_id(),
882 )
883 .await
884 .expect("failed to read unthreaded user room receipt after save")
885 .unwrap();
886 assert_eq!(unthreaded_user_receipt_event_id, first_event_id);
887 assert_eq!(unthreaded_user_receipt.ts.unwrap().0, first_receipt_ts);
888 let first_event_unthreaded_receipts = self
889 .get_event_room_receipt_events(
890 room_id,
891 ReceiptType::Read,
892 ReceiptThread::Unthreaded,
893 first_event_id,
894 )
895 .await
896 .expect("failed to read unthreaded event room receipt for 1 after save");
897 assert_eq!(
898 first_event_unthreaded_receipts.len(),
899 1,
900 "Found a wrong number of unthreaded receipts for 1 after save"
901 );
902 assert_eq!(first_event_unthreaded_receipts[0].0, user_id());
903 assert_eq!(first_event_unthreaded_receipts[0].1.ts.unwrap().0, first_receipt_ts);
904 assert!(
905 self.get_event_room_receipt_events(
906 room_id,
907 ReceiptType::Read,
908 ReceiptThread::Unthreaded,
909 second_event_id
910 )
911 .await
912 .expect("failed to read unthreaded event room receipt for 2 after save")
913 .is_empty()
914 );
915
916 let mut changes = StateChanges::default();
917 changes.add_receipts(room_id, second_receipt_event);
918
919 self.save_changes(&changes).await.expect("Saving works");
920 let (unthreaded_user_receipt_event_id, unthreaded_user_receipt) = self
921 .get_user_room_receipt_event(
922 room_id,
923 ReceiptType::Read,
924 ReceiptThread::Unthreaded,
925 user_id(),
926 )
927 .await
928 .expect("Getting unthreaded user room receipt after save failed")
929 .unwrap();
930 assert_eq!(unthreaded_user_receipt_event_id, second_event_id);
931 assert_eq!(unthreaded_user_receipt.ts.unwrap().0, second_receipt_ts);
932 assert!(
933 self.get_event_room_receipt_events(
934 room_id,
935 ReceiptType::Read,
936 ReceiptThread::Unthreaded,
937 first_event_id
938 )
939 .await
940 .expect("Getting unthreaded event room receipt events for first event failed")
941 .is_empty()
942 );
943 let second_event_unthreaded_receipts = self
944 .get_event_room_receipt_events(
945 room_id,
946 ReceiptType::Read,
947 ReceiptThread::Unthreaded,
948 second_event_id,
949 )
950 .await
951 .expect("Getting unthreaded event room receipt events for second event failed");
952 assert_eq!(
953 second_event_unthreaded_receipts.len(),
954 1,
955 "Found a wrong number of unthreaded receipts for second event after save"
956 );
957 assert_eq!(second_event_unthreaded_receipts[0].0, user_id());
958 assert_eq!(second_event_unthreaded_receipts[0].1.ts.unwrap().0, second_receipt_ts);
959
960 assert!(
961 self.get_user_room_receipt_event(
962 room_id,
963 ReceiptType::Read,
964 ReceiptThread::Main,
965 user_id()
966 )
967 .await
968 .expect("failed to read threaded user room receipt")
969 .is_none()
970 );
971 assert!(
972 self.get_event_room_receipt_events(
973 room_id,
974 ReceiptType::Read,
975 ReceiptThread::Main,
976 second_event_id
977 )
978 .await
979 .expect("Getting threaded event room receipts for 2 failed")
980 .is_empty()
981 );
982
983 let mut changes = StateChanges::default();
984 changes.add_receipts(room_id, third_receipt_event);
985
986 self.save_changes(&changes).await.expect("Saving works");
987 let (unthreaded_user_receipt_event_id, unthreaded_user_receipt) = self
989 .get_user_room_receipt_event(
990 room_id,
991 ReceiptType::Read,
992 ReceiptThread::Unthreaded,
993 user_id(),
994 )
995 .await
996 .expect("Getting unthreaded user room receipt after save failed")
997 .unwrap();
998 assert_eq!(unthreaded_user_receipt_event_id, second_event_id);
999 assert_eq!(unthreaded_user_receipt.ts.unwrap().0, second_receipt_ts);
1000 let second_event_unthreaded_receipts = self
1001 .get_event_room_receipt_events(
1002 room_id,
1003 ReceiptType::Read,
1004 ReceiptThread::Unthreaded,
1005 second_event_id,
1006 )
1007 .await
1008 .expect("Getting unthreaded event room receipt events for second event failed");
1009 assert_eq!(
1010 second_event_unthreaded_receipts.len(),
1011 1,
1012 "Found a wrong number of unthreaded receipts for second event after save"
1013 );
1014 assert_eq!(second_event_unthreaded_receipts[0].0, user_id());
1015 assert_eq!(second_event_unthreaded_receipts[0].1.ts.unwrap().0, second_receipt_ts);
1016 let (threaded_user_receipt_event_id, threaded_user_receipt) = self
1018 .get_user_room_receipt_event(room_id, ReceiptType::Read, ReceiptThread::Main, user_id())
1019 .await
1020 .expect("Getting threaded user room receipt after save failed")
1021 .unwrap();
1022 assert_eq!(threaded_user_receipt_event_id, second_event_id);
1023 assert_eq!(threaded_user_receipt.ts.unwrap().0, third_receipt_ts);
1024 let second_event_threaded_receipts = self
1025 .get_event_room_receipt_events(
1026 room_id,
1027 ReceiptType::Read,
1028 ReceiptThread::Main,
1029 second_event_id,
1030 )
1031 .await
1032 .expect("Getting threaded event room receipt events for second event failed");
1033 assert_eq!(
1034 second_event_threaded_receipts.len(),
1035 1,
1036 "Found a wrong number of threaded receipts for second event after save"
1037 );
1038 assert_eq!(second_event_threaded_receipts[0].0, user_id());
1039 assert_eq!(second_event_threaded_receipts[0].1.ts.unwrap().0, third_receipt_ts);
1040
1041 Ok(())
1042 }
1043
1044 async fn test_custom_storage(&self) -> TestResult {
1045 let key = "my_key";
1046 let value = &[0, 1, 2, 3];
1047
1048 self.set_custom_value(key.as_bytes(), value.to_vec()).await?;
1049
1050 let read = self.get_custom_value(key.as_bytes()).await?;
1051
1052 assert_eq!(Some(value.as_ref()), read.as_deref());
1053
1054 Ok(())
1055 }
1056
1057 async fn test_stripped_non_stripped(&self) -> TestResult {
1058 let room_id = room_id!("!test_stripped_non_stripped:localhost");
1059 let user_id = user_id();
1060
1061 assert!(self.get_member_event(room_id, user_id).await?.is_none());
1062 assert_eq!(self.get_room_infos(&RoomLoadSettings::default()).await?.len(), 0);
1063
1064 let mut changes = StateChanges::default();
1065 changes
1066 .state
1067 .entry(room_id.to_owned())
1068 .or_default()
1069 .entry(StateEventType::RoomMember)
1070 .or_default()
1071 .insert(user_id.into(), membership_event().cast());
1072 changes.add_room(RoomInfo::new(room_id, RoomState::Left));
1073 self.save_changes(&changes).await?;
1074
1075 let member_event = self.get_member_event(room_id, user_id).await?.unwrap().deserialize()?;
1076 assert!(matches!(member_event, MemberEvent::Sync(_)));
1077 assert_eq!(self.get_room_infos(&RoomLoadSettings::default()).await?.len(), 1);
1078
1079 let members = self.get_user_ids(room_id, RoomMemberships::empty()).await?;
1080 assert_eq!(members, vec![user_id.to_owned()]);
1081
1082 let mut changes = StateChanges::default();
1083 changes.add_stripped_member(room_id, user_id, custom_stripped_membership_event(user_id));
1084 changes.add_room(RoomInfo::new(room_id, RoomState::Invited));
1085 self.save_changes(&changes).await?;
1086
1087 let member_event = self.get_member_event(room_id, user_id).await?.unwrap().deserialize()?;
1088 assert!(matches!(member_event, MemberEvent::Stripped(_)));
1089 assert_eq!(self.get_room_infos(&RoomLoadSettings::default()).await?.len(), 1);
1090
1091 let members = self.get_user_ids(room_id, RoomMemberships::empty()).await?;
1092 assert_eq!(members, vec![user_id.to_owned()]);
1093
1094 Ok(())
1095 }
1096
1097 async fn test_room_removal(&self) -> TestResult {
1098 let room_id = room_id();
1099 let user_id = user_id();
1100 let display_name = DisplayName::new("example");
1101 let stripped_room_id = stripped_room_id();
1102
1103 self.populate().await?;
1104
1105 {
1106 let txn = TransactionId::new();
1108 let ev =
1109 SerializableEventContent::new(&RoomMessageEventContent::text_plain("sup").into())?;
1110 self.save_send_queue_request(
1111 room_id,
1112 txn.clone(),
1113 MilliSecondsSinceUnixEpoch::now(),
1114 ev.into(),
1115 0,
1116 )
1117 .await?;
1118
1119 self.save_dependent_queued_request(
1121 room_id,
1122 &txn,
1123 ChildTransactionId::new(),
1124 MilliSecondsSinceUnixEpoch::now(),
1125 DependentQueuedRequestKind::RedactEvent,
1126 )
1127 .await?;
1128 }
1129
1130 self.remove_room(room_id).await?;
1131
1132 assert_eq!(
1133 self.get_room_infos(&RoomLoadSettings::default()).await?.len(),
1134 1,
1135 "room is still there"
1136 );
1137
1138 assert!(self.get_state_event(room_id, StateEventType::RoomName, "").await?.is_none());
1139 assert!(
1140 self.get_state_events(room_id, StateEventType::RoomTopic).await?.is_empty(),
1141 "still state events found"
1142 );
1143 assert!(self.get_profile(room_id, user_id).await?.is_none());
1144 assert!(self.get_member_event(room_id, user_id).await?.is_none());
1145 assert!(
1146 self.get_user_ids(room_id, RoomMemberships::empty()).await?.is_empty(),
1147 "still user ids found"
1148 );
1149 assert!(
1150 self.get_user_ids(room_id, RoomMemberships::INVITE).await?.is_empty(),
1151 "still invited user ids found"
1152 );
1153 assert!(
1154 self.get_user_ids(room_id, RoomMemberships::JOIN).await?.is_empty(),
1155 "still joined users found"
1156 );
1157 assert!(
1158 self.get_users_with_display_name(room_id, &display_name).await?.is_empty(),
1159 "still display names found"
1160 );
1161 assert!(
1162 self.get_room_account_data_event(room_id, RoomAccountDataEventType::Tag)
1163 .await?
1164 .is_none()
1165 );
1166 assert!(
1167 self.get_user_room_receipt_event(
1168 room_id,
1169 ReceiptType::Read,
1170 ReceiptThread::Unthreaded,
1171 user_id
1172 )
1173 .await?
1174 .is_none()
1175 );
1176 assert!(
1177 self.get_event_room_receipt_events(
1178 room_id,
1179 ReceiptType::Read,
1180 ReceiptThread::Unthreaded,
1181 first_receipt_event_id()
1182 )
1183 .await?
1184 .is_empty(),
1185 "still event recepts in the store"
1186 );
1187 assert!(self.load_send_queue_requests(room_id).await?.is_empty());
1188 assert!(self.load_dependent_queued_requests(room_id).await?.is_empty());
1189
1190 self.remove_room(stripped_room_id).await?;
1191
1192 assert!(
1193 self.get_room_infos(&RoomLoadSettings::default()).await?.is_empty(),
1194 "still room info found"
1195 );
1196 Ok(())
1197 }
1198
1199 async fn test_profile_removal(&self) -> TestResult {
1200 let room_id = room_id();
1201
1202 let user_id = user_id();
1204 let invited_user_id = invited_user_id();
1205
1206 self.populate().await?;
1207
1208 let new_invite_member_json = json!({
1209 "content": {
1210 "avatar_url": "mxc://localhost/SEsfnsuifSDFSSEG",
1211 "displayname": "example after update",
1212 "membership": "invite",
1213 "reason": "Looking for support"
1214 },
1215 "event_id": "$143273582443PhrSm:localhost",
1216 "origin_server_ts": 1432735824,
1217 "room_id": room_id,
1218 "sender": user_id,
1219 "state_key": invited_user_id,
1220 "type": "m.room.member",
1221 });
1222 let new_invite_member_event: SyncRoomMemberEvent =
1223 serde_json::from_value(new_invite_member_json.clone())?;
1224
1225 let mut changes = StateChanges {
1226 profiles_to_delete: [(
1228 room_id.to_owned(),
1229 vec![user_id.to_owned(), invited_user_id.to_owned()],
1230 )]
1231 .into(),
1232
1233 profiles: {
1235 let mut map = BTreeMap::default();
1236 map.insert(
1237 room_id.to_owned(),
1238 [(invited_user_id.to_owned(), new_invite_member_event.into())]
1239 .into_iter()
1240 .collect(),
1241 );
1242 map
1243 },
1244
1245 ..StateChanges::default()
1246 };
1247
1248 let raw = serde_json::from_value::<Raw<AnySyncStateEvent>>(new_invite_member_json)
1249 .expect("can create sync-state-event for topic");
1250 let event = raw.deserialize()?;
1251 changes.add_state_event(room_id, event, raw);
1252
1253 self.save_changes(&changes).await?;
1254
1255 assert!(self.get_profile(room_id, user_id).await?.is_none());
1257 assert!(self.get_member_event(room_id, user_id).await?.is_some());
1258
1259 let invited_member_event = self.get_profile(room_id, invited_user_id).await?.unwrap();
1261 assert_eq!(
1262 invited_member_event.content.displayname.as_deref(),
1263 Some("example after update")
1264 );
1265 assert!(self.get_member_event(room_id, invited_user_id).await?.is_some());
1266
1267 Ok(())
1268 }
1269
1270 async fn test_presence_saving(&self) -> TestResult {
1271 let user_id = user_id();
1272 let second_user_id = user_id!("@second:localhost");
1273 let third_user_id = user_id!("@third:localhost");
1274 let unknown_user_id = user_id!("@unknown:localhost");
1275
1276 let mut user_ids = vec![user_id.to_owned()];
1278 let presence_event = self.get_presence_event(user_id).await;
1279 assert!(presence_event?.is_none());
1280 let presence_events = self.get_presence_events(&user_ids).await;
1281 assert!(presence_events?.is_empty());
1282
1283 let mut changes = StateChanges::default();
1285 changes.presence.insert(user_id.to_owned(), custom_presence_event(user_id));
1286 self.save_changes(&changes).await?;
1287
1288 let presence_event = self.get_presence_event(user_id).await;
1289 assert!(presence_event?.is_some());
1290 let presence_events = self.get_presence_events(&user_ids).await;
1291 assert_eq!(presence_events?.len(), 1);
1292
1293 let mut changes = StateChanges::default();
1295 changes.presence.insert(second_user_id.to_owned(), custom_presence_event(second_user_id));
1296 changes.presence.insert(third_user_id.to_owned(), custom_presence_event(third_user_id));
1297 self.save_changes(&changes).await?;
1298
1299 user_ids.extend([second_user_id.to_owned(), third_user_id.to_owned()]);
1300 let presence_event = self.get_presence_event(second_user_id).await;
1301 assert!(presence_event?.is_some());
1302 let presence_event = self.get_presence_event(third_user_id).await;
1303 assert!(presence_event?.is_some());
1304 let presence_events = self.get_presence_events(&user_ids).await;
1305 assert_eq!(presence_events?.len(), 3);
1306
1307 user_ids.push(unknown_user_id.to_owned());
1309 let member_events = self.get_presence_events(&user_ids).await;
1310 assert_eq!(member_events?.len(), 3);
1311
1312 let presence_events = self.get_presence_events(&[]).await;
1314 assert!(presence_events?.is_empty());
1315
1316 Ok(())
1317 }
1318
1319 async fn test_display_names_saving(&self) -> TestResult {
1320 let room_id = room_id!("!test_display_names_saving:localhost");
1321 let user_id = user_id();
1322 let user_display_name = DisplayName::new("User");
1323 let second_user_id = user_id!("@second:localhost");
1324 let third_user_id = user_id!("@third:localhost");
1325 let other_display_name = DisplayName::new("Raoul");
1326 let unknown_display_name = DisplayName::new("Unknown");
1327
1328 let mut display_names = vec![user_display_name.to_owned()];
1330 let users = self.get_users_with_display_name(room_id, &user_display_name).await?;
1331 assert!(users.is_empty());
1332 let names = self.get_users_with_display_names(room_id, &display_names).await?;
1333 assert!(names.is_empty());
1334
1335 let mut changes = StateChanges::default();
1337 changes
1338 .ambiguity_maps
1339 .entry(room_id.to_owned())
1340 .or_default()
1341 .insert(user_display_name.to_owned(), [user_id.to_owned()].into());
1342 self.save_changes(&changes).await?;
1343
1344 let users = self.get_users_with_display_name(room_id, &user_display_name).await?;
1345 assert_eq!(users.len(), 1);
1346 let names = self.get_users_with_display_names(room_id, &display_names).await?;
1347 assert_eq!(names.len(), 1);
1348 assert_eq!(names.get(&user_display_name).unwrap().len(), 1);
1349
1350 let mut changes = StateChanges::default();
1352 changes.ambiguity_maps.entry(room_id.to_owned()).or_default().insert(
1353 other_display_name.to_owned(),
1354 [second_user_id.to_owned(), third_user_id.to_owned()].into(),
1355 );
1356 self.save_changes(&changes).await?;
1357
1358 display_names.push(other_display_name.to_owned());
1359 let users = self.get_users_with_display_name(room_id, &user_display_name).await?;
1360 assert_eq!(users.len(), 1);
1361 let users = self.get_users_with_display_name(room_id, &other_display_name).await?;
1362 assert_eq!(users.len(), 2);
1363 let names = self.get_users_with_display_names(room_id, &display_names).await?;
1364 assert_eq!(names.len(), 2);
1365 assert_eq!(names.get(&user_display_name).unwrap().len(), 1);
1366 assert_eq!(names.get(&other_display_name).unwrap().len(), 2);
1367
1368 display_names.push(unknown_display_name.to_owned());
1370 let names = self.get_users_with_display_names(room_id, &display_names).await?;
1371 assert_eq!(names.len(), 2);
1372
1373 let names = self.get_users_with_display_names(room_id, &[]).await?;
1375 assert!(names.is_empty());
1376
1377 Ok(())
1378 }
1379
1380 #[allow(clippy::needless_range_loop)]
1381 async fn test_send_queue(&self) -> TestResult {
1382 let room_id = room_id!("!test_send_queue:localhost");
1383
1384 let events = self.load_send_queue_requests(room_id).await?;
1386 assert!(events.is_empty());
1387
1388 let txn0 = TransactionId::new();
1390 let event0 =
1391 SerializableEventContent::new(&RoomMessageEventContent::text_plain("msg0").into())?;
1392 self.save_send_queue_request(
1393 room_id,
1394 txn0.clone(),
1395 MilliSecondsSinceUnixEpoch::now(),
1396 event0.into(),
1397 0,
1398 )
1399 .await?;
1400
1401 let pending = self.load_send_queue_requests(room_id).await?;
1403
1404 assert_eq!(pending.len(), 1);
1405 {
1406 assert_eq!(pending[0].transaction_id, txn0);
1407
1408 let deserialized = pending[0].as_event().unwrap().deserialize()?;
1409 assert_let!(AnyMessageLikeEventContent::RoomMessage(content) = deserialized);
1410 assert_eq!(content.body(), "msg0");
1411
1412 assert!(!pending[0].is_wedged());
1413 }
1414
1415 for i in 1..=3 {
1417 let txn = TransactionId::new();
1418 let event = SerializableEventContent::new(
1419 &RoomMessageEventContent::text_plain(format!("msg{i}")).into(),
1420 )?;
1421
1422 self.save_send_queue_request(
1423 room_id,
1424 txn,
1425 MilliSecondsSinceUnixEpoch::now(),
1426 event.into(),
1427 0,
1428 )
1429 .await?;
1430 }
1431
1432 let pending = self.load_send_queue_requests(room_id).await?;
1434
1435 assert_eq!(pending.len(), 4);
1437
1438 assert_eq!(pending[0].transaction_id, txn0);
1439
1440 for i in 0..4 {
1441 let deserialized = pending[i].as_event().unwrap().deserialize()?;
1442 assert_let!(AnyMessageLikeEventContent::RoomMessage(content) = deserialized);
1443 assert_eq!(content.body(), format!("msg{i}"));
1444 assert!(!pending[i].is_wedged());
1445 }
1446
1447 let txn2 = &pending[2].transaction_id;
1449 self.update_send_queue_request_status(
1450 room_id,
1451 txn2,
1452 Some(QueueWedgeError::GenericApiError { msg: "Oops".to_owned() }),
1453 )
1454 .await?;
1455
1456 let pending = self.load_send_queue_requests(room_id).await?;
1458
1459 assert_eq!(pending.len(), 4);
1461 assert_eq!(pending[0].transaction_id, txn0);
1462 assert_eq!(pending[2].transaction_id, *txn2);
1463 assert!(pending[2].is_wedged());
1464 let error = pending[2].clone().error.unwrap();
1465 let generic_error = assert_matches!(error, QueueWedgeError::GenericApiError { msg } => msg);
1466 assert_eq!(generic_error, "Oops");
1467 for i in 0..4 {
1468 if i != 2 {
1469 assert!(!pending[i].is_wedged());
1470 }
1471 }
1472
1473 let event0 = SerializableEventContent::new(
1475 &RoomMessageEventContent::text_plain("wow that's a cool test").into(),
1476 )?;
1477 self.update_send_queue_request(room_id, txn2, event0.into()).await?;
1478
1479 let pending = self.load_send_queue_requests(room_id).await?;
1481
1482 assert_eq!(pending.len(), 4);
1483 {
1484 assert_eq!(pending[2].transaction_id, *txn2);
1485
1486 let deserialized = pending[2].as_event().unwrap().deserialize()?;
1487 assert_let!(AnyMessageLikeEventContent::RoomMessage(content) = deserialized);
1488 assert_eq!(content.body(), "wow that's a cool test");
1489
1490 assert!(!pending[2].is_wedged());
1491
1492 for i in 0..4 {
1493 if i != 2 {
1494 let deserialized = pending[i].as_event().unwrap().deserialize()?;
1495 assert_let!(AnyMessageLikeEventContent::RoomMessage(content) = deserialized);
1496 assert_eq!(content.body(), format!("msg{i}"));
1497
1498 assert!(!pending[i].is_wedged());
1499 }
1500 }
1501 }
1502
1503 self.remove_send_queue_request(room_id, &txn0).await?;
1505
1506 let pending = self.load_send_queue_requests(room_id).await?;
1508
1509 assert_eq!(pending.len(), 3);
1510 assert_eq!(pending[1].transaction_id, *txn2);
1511 for i in 0..3 {
1512 assert_ne!(pending[i].transaction_id, txn0);
1513 }
1514
1515 let room_id2 = room_id!("!test_send_queue_two:localhost");
1520 {
1521 let txn = TransactionId::new();
1522 let event = SerializableEventContent::new(
1523 &RoomMessageEventContent::text_plain("room2").into(),
1524 )?;
1525 self.save_send_queue_request(
1526 room_id2,
1527 txn.clone(),
1528 MilliSecondsSinceUnixEpoch::now(),
1529 event.into(),
1530 0,
1531 )
1532 .await?;
1533 }
1534
1535 {
1537 let room_id3 = room_id!("!test_send_queue_three:localhost");
1538 let txn = TransactionId::new();
1539 let event = SerializableEventContent::new(
1540 &RoomMessageEventContent::text_plain("room3").into(),
1541 )?;
1542 self.save_send_queue_request(
1543 room_id3,
1544 txn.clone(),
1545 MilliSecondsSinceUnixEpoch::now(),
1546 event.into(),
1547 0,
1548 )
1549 .await?;
1550
1551 self.remove_send_queue_request(room_id3, &txn).await?;
1552 }
1553
1554 let outstanding_rooms = self.load_rooms_with_unsent_requests().await?;
1557 assert_eq!(outstanding_rooms.len(), 2);
1558 assert!(outstanding_rooms.iter().any(|room| room == room_id));
1559 assert!(outstanding_rooms.iter().any(|room| room == room_id2));
1560
1561 Ok(())
1562 }
1563
1564 async fn test_send_queue_priority(&self) -> TestResult {
1565 let room_id = room_id!("!test_send_queue:localhost");
1566
1567 let events = self.load_send_queue_requests(room_id).await?;
1569 assert!(events.is_empty());
1570
1571 let low0_txn = TransactionId::new();
1573 let ev0 =
1574 SerializableEventContent::new(&RoomMessageEventContent::text_plain("low0").into())?;
1575 self.save_send_queue_request(
1576 room_id,
1577 low0_txn.clone(),
1578 MilliSecondsSinceUnixEpoch::now(),
1579 ev0.into(),
1580 2,
1581 )
1582 .await?;
1583
1584 let high_txn = TransactionId::new();
1586 let ev1 =
1587 SerializableEventContent::new(&RoomMessageEventContent::text_plain("high").into())?;
1588 self.save_send_queue_request(
1589 room_id,
1590 high_txn.clone(),
1591 MilliSecondsSinceUnixEpoch::now(),
1592 ev1.into(),
1593 10,
1594 )
1595 .await?;
1596
1597 let low1_txn = TransactionId::new();
1599 let ev2 =
1600 SerializableEventContent::new(&RoomMessageEventContent::text_plain("low1").into())?;
1601 self.save_send_queue_request(
1602 room_id,
1603 low1_txn.clone(),
1604 MilliSecondsSinceUnixEpoch::now(),
1605 ev2.into(),
1606 2,
1607 )
1608 .await?;
1609
1610 let pending = self.load_send_queue_requests(room_id).await?;
1613
1614 assert_eq!(pending.len(), 3);
1615 {
1616 assert_eq!(pending[0].transaction_id, high_txn);
1617
1618 let deserialized = pending[0].as_event().unwrap().deserialize()?;
1619 assert_let!(AnyMessageLikeEventContent::RoomMessage(content) = deserialized);
1620 assert_eq!(content.body(), "high");
1621 }
1622
1623 {
1624 assert_eq!(pending[1].transaction_id, low0_txn);
1625
1626 let deserialized = pending[1].as_event().unwrap().deserialize()?;
1627 assert_let!(AnyMessageLikeEventContent::RoomMessage(content) = deserialized);
1628 assert_eq!(content.body(), "low0");
1629 }
1630
1631 {
1632 assert_eq!(pending[2].transaction_id, low1_txn);
1633
1634 let deserialized = pending[2].as_event().unwrap().deserialize()?;
1635 assert_let!(AnyMessageLikeEventContent::RoomMessage(content) = deserialized);
1636 assert_eq!(content.body(), "low1");
1637 }
1638
1639 Ok(())
1640 }
1641
1642 async fn test_send_queue_dependents(&self) -> TestResult {
1643 let room_id = room_id!("!test_send_queue_dependents:localhost");
1644
1645 let txn0 = TransactionId::new();
1647 let event0 =
1648 SerializableEventContent::new(&RoomMessageEventContent::text_plain("hey").into())?;
1649 self.save_send_queue_request(
1650 room_id,
1651 txn0.clone(),
1652 MilliSecondsSinceUnixEpoch::now(),
1653 event0.clone().into(),
1654 0,
1655 )
1656 .await?;
1657
1658 assert!(self.load_dependent_queued_requests(room_id).await?.is_empty());
1660
1661 let child_txn = ChildTransactionId::new();
1663 self.save_dependent_queued_request(
1664 room_id,
1665 &txn0,
1666 child_txn.clone(),
1667 MilliSecondsSinceUnixEpoch::now(),
1668 DependentQueuedRequestKind::RedactEvent,
1669 )
1670 .await?;
1671
1672 let dependents = self.load_dependent_queued_requests(room_id).await?;
1674 assert_eq!(dependents.len(), 1);
1675 assert_eq!(dependents[0].parent_transaction_id, txn0);
1676 assert_eq!(dependents[0].own_transaction_id, child_txn);
1677 assert!(dependents[0].parent_key.is_none());
1678 assert_matches!(dependents[0].kind, DependentQueuedRequestKind::RedactEvent);
1679
1680 let (event, event_type) = event0.raw();
1682 let event_id = owned_event_id!("$1");
1683 let num_updated = self
1684 .mark_dependent_queued_requests_as_ready(
1685 room_id,
1686 &txn0,
1687 SentRequestKey::Event {
1688 event_id: event_id.clone(),
1689 event: event.clone(),
1690 event_type: event_type.to_owned(),
1691 },
1692 )
1693 .await?;
1694 assert_eq!(num_updated, 1);
1695
1696 let dependents = self.load_dependent_queued_requests(room_id).await?;
1698 assert_eq!(dependents.len(), 1);
1699 assert_eq!(dependents[0].parent_transaction_id, txn0);
1700 assert_eq!(dependents[0].own_transaction_id, child_txn);
1701 assert_matches!(
1702 dependents[0].parent_key.as_ref(),
1703 Some(SentRequestKey::Event {
1704 event_id: received_event_id,
1705 event: received_event,
1706 event_type: received_event_type
1707 }) => {
1708 assert_eq!(received_event_id, &event_id);
1709 assert_eq!(received_event.json().to_string(), event.json().to_string());
1710 assert_eq!(received_event_type.as_str(), event_type);
1711 }
1712 );
1713 assert_matches!(dependents[0].kind, DependentQueuedRequestKind::RedactEvent);
1714
1715 let removed = self
1717 .remove_dependent_queued_request(room_id, &dependents[0].own_transaction_id)
1718 .await?;
1719 assert!(removed);
1720
1721 assert!(self.load_dependent_queued_requests(room_id).await?.is_empty());
1723
1724 let txn1 = TransactionId::new();
1727 let event1 =
1728 SerializableEventContent::new(&RoomMessageEventContent::text_plain("hey2").into())?;
1729 self.save_send_queue_request(
1730 room_id,
1731 txn1.clone(),
1732 MilliSecondsSinceUnixEpoch::now(),
1733 event1.into(),
1734 0,
1735 )
1736 .await?;
1737
1738 self.save_dependent_queued_request(
1739 room_id,
1740 &txn0,
1741 ChildTransactionId::new(),
1742 MilliSecondsSinceUnixEpoch::now(),
1743 DependentQueuedRequestKind::RedactEvent,
1744 )
1745 .await?;
1746 assert_eq!(self.load_dependent_queued_requests(room_id).await?.len(), 1);
1747
1748 self.save_dependent_queued_request(
1749 room_id,
1750 &txn1,
1751 ChildTransactionId::new(),
1752 MilliSecondsSinceUnixEpoch::now(),
1753 DependentQueuedRequestKind::EditEvent {
1754 new_content: SerializableEventContent::new(
1755 &RoomMessageEventContent::text_plain("edit").into(),
1756 )?,
1757 },
1758 )
1759 .await?;
1760 assert_eq!(self.load_dependent_queued_requests(room_id).await?.len(), 2);
1761
1762 let removed = self.remove_send_queue_request(room_id, &txn0).await?;
1764 assert!(removed);
1765
1766 let dependents = self.load_dependent_queued_requests(room_id).await?;
1768 assert_eq!(dependents.len(), 2);
1769
1770 Ok(())
1771 }
1772
1773 async fn test_update_send_queue_dependent(&self) -> TestResult {
1774 let room_id = room_id!("!test_send_queue_dependents:localhost");
1775
1776 let txn = TransactionId::new();
1777
1778 let child_txn = ChildTransactionId::new();
1780
1781 self.save_dependent_queued_request(
1782 room_id,
1783 &txn,
1784 child_txn.clone(),
1785 MilliSecondsSinceUnixEpoch::now(),
1786 DependentQueuedRequestKind::RedactEvent,
1787 )
1788 .await?;
1789
1790 let dependents = self.load_dependent_queued_requests(room_id).await?;
1792 assert_eq!(dependents.len(), 1);
1793 assert_eq!(dependents[0].parent_transaction_id, txn);
1794 assert_eq!(dependents[0].own_transaction_id, child_txn);
1795 assert!(dependents[0].parent_key.is_none());
1796 assert_matches!(dependents[0].kind, DependentQueuedRequestKind::RedactEvent);
1797
1798 self.update_dependent_queued_request(
1800 room_id,
1801 &child_txn,
1802 DependentQueuedRequestKind::ReactEvent { key: "👍".to_owned() },
1803 )
1804 .await?;
1805
1806 let dependents = self.load_dependent_queued_requests(room_id).await?;
1808 assert_eq!(dependents.len(), 1);
1809 assert_eq!(dependents[0].parent_transaction_id, txn);
1810 assert_eq!(dependents[0].own_transaction_id, child_txn);
1811 assert!(dependents[0].parent_key.is_none());
1812 assert_matches!(
1813 &dependents[0].kind,
1814 DependentQueuedRequestKind::ReactEvent { key } => {
1815 assert_eq!(key, "👍");
1816 }
1817 );
1818
1819 Ok(())
1820 }
1821
1822 async fn test_get_room_infos(&self) -> TestResult {
1823 let room_id_0 = room_id!("!r0");
1824 let room_id_1 = room_id!("!r1");
1825 let room_id_2 = room_id!("!r2");
1826
1827 {
1829 assert_eq!(self.get_room_infos(&RoomLoadSettings::default()).await?.len(), 0);
1830 }
1831
1832 let mut changes = StateChanges::default();
1834 changes.add_room(RoomInfo::new(room_id_0, RoomState::Joined));
1835 changes.add_room(RoomInfo::new(room_id_1, RoomState::Joined));
1836 self.save_changes(&changes).await?;
1837
1838 {
1840 let mut all_rooms = self.get_room_infos(&RoomLoadSettings::All).await?;
1841
1842 all_rooms.sort_by(|a, b| a.room_id.cmp(&b.room_id));
1845
1846 assert_eq!(all_rooms.len(), 2);
1847 assert_eq!(all_rooms[0].room_id, room_id_0);
1848 assert_eq!(all_rooms[1].room_id, room_id_1);
1849 }
1850
1851 {
1853 let all_rooms =
1854 self.get_room_infos(&RoomLoadSettings::One(room_id_1.to_owned())).await?;
1855
1856 assert_eq!(all_rooms.len(), 1);
1857 assert_eq!(all_rooms[0].room_id, room_id_1);
1858 }
1859
1860 {
1863 let all_rooms =
1864 self.get_room_infos(&RoomLoadSettings::One(room_id_2.to_owned())).await?;
1865
1866 assert_eq!(all_rooms.len(), 0);
1867 }
1868
1869 Ok(())
1870 }
1871
1872 async fn test_thread_subscriptions(&self) -> TestResult {
1873 let first_thread = event_id!("$t1");
1874 let second_thread = event_id!("$t2");
1875
1876 let maybe_sub = self.load_thread_subscription(room_id(), first_thread).await?;
1878 assert!(maybe_sub.is_none());
1879
1880 let maybe_sub = self.load_thread_subscription(room_id(), second_thread).await?;
1881 assert!(maybe_sub.is_none());
1882
1883 self.upsert_thread_subscriptions(vec![(
1885 room_id(),
1886 first_thread,
1887 StoredThreadSubscription {
1888 status: ThreadSubscriptionStatus::Subscribed { automatic: true },
1889 bump_stamp: None,
1890 },
1891 )])
1892 .await?;
1893
1894 self.upsert_thread_subscriptions(vec![(
1895 room_id(),
1896 second_thread,
1897 StoredThreadSubscription {
1898 status: ThreadSubscriptionStatus::Subscribed { automatic: false },
1899 bump_stamp: None,
1900 },
1901 )])
1902 .await?;
1903
1904 let maybe_sub = self.load_thread_subscription(room_id(), first_thread).await?;
1906 assert_eq!(
1907 maybe_sub,
1908 Some(StoredThreadSubscription {
1909 status: ThreadSubscriptionStatus::Subscribed { automatic: true },
1910 bump_stamp: None,
1911 })
1912 );
1913
1914 let maybe_sub = self.load_thread_subscription(room_id(), second_thread).await?;
1915 assert_eq!(
1916 maybe_sub,
1917 Some(StoredThreadSubscription {
1918 status: ThreadSubscriptionStatus::Subscribed { automatic: false },
1919 bump_stamp: None,
1920 })
1921 );
1922
1923 self.upsert_thread_subscriptions(vec![(
1925 room_id(),
1926 first_thread,
1927 StoredThreadSubscription {
1928 status: ThreadSubscriptionStatus::Unsubscribed,
1929 bump_stamp: None,
1930 },
1931 )])
1932 .await?;
1933
1934 let maybe_sub = self.load_thread_subscription(room_id(), first_thread).await?;
1936 assert_eq!(
1937 maybe_sub,
1938 Some(StoredThreadSubscription {
1939 status: ThreadSubscriptionStatus::Unsubscribed,
1940 bump_stamp: None,
1941 })
1942 );
1943
1944 let maybe_sub = self.load_thread_subscription(room_id(), second_thread).await?;
1946 assert_eq!(
1947 maybe_sub,
1948 Some(StoredThreadSubscription {
1949 status: ThreadSubscriptionStatus::Subscribed { automatic: false },
1950 bump_stamp: None,
1951 })
1952 );
1953
1954 self.remove_thread_subscription(room_id(), second_thread).await?;
1956
1957 let maybe_sub = self.load_thread_subscription(room_id(), second_thread).await?;
1959 assert_eq!(maybe_sub, None);
1960
1961 let maybe_sub = self.load_thread_subscription(room_id(), first_thread).await?;
1963 assert_eq!(
1964 maybe_sub,
1965 Some(StoredThreadSubscription {
1966 status: ThreadSubscriptionStatus::Unsubscribed,
1967 bump_stamp: None,
1968 })
1969 );
1970
1971 self.remove_thread_subscription(room_id(), second_thread).await?;
1973
1974 Ok(())
1975 }
1976
1977 async fn test_thread_subscriptions_bulk_upsert(&self) -> TestResult {
1978 let threads = [
1979 event_id!("$t1"),
1980 event_id!("$t2"),
1981 event_id!("$t3"),
1982 event_id!("$t4"),
1983 event_id!("$t5"),
1984 event_id!("$t6"),
1985 ];
1986 let build_subscription_updates = |subs: &[StoredThreadSubscription]| {
1989 threads
1990 .iter()
1991 .zip(subs)
1992 .map(|(&event_id, &sub)| (room_id(), event_id, sub))
1993 .collect::<Vec<_>>()
1994 };
1995
1996 let initial_subscriptions = build_subscription_updates(&[
1998 StoredThreadSubscription {
1999 status: ThreadSubscriptionStatus::Unsubscribed,
2000 bump_stamp: None,
2001 },
2002 StoredThreadSubscription {
2003 status: ThreadSubscriptionStatus::Unsubscribed,
2004 bump_stamp: Some(14),
2005 },
2006 StoredThreadSubscription {
2007 status: ThreadSubscriptionStatus::Unsubscribed,
2008 bump_stamp: None,
2009 },
2010 StoredThreadSubscription {
2011 status: ThreadSubscriptionStatus::Unsubscribed,
2012 bump_stamp: Some(210),
2013 },
2014 StoredThreadSubscription {
2015 status: ThreadSubscriptionStatus::Unsubscribed,
2016 bump_stamp: Some(5),
2017 },
2018 StoredThreadSubscription {
2019 status: ThreadSubscriptionStatus::Unsubscribed,
2020 bump_stamp: Some(100),
2021 },
2022 ]);
2023
2024 let update_subscriptions = build_subscription_updates(&[
2025 StoredThreadSubscription {
2026 status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2027 bump_stamp: None,
2028 },
2029 StoredThreadSubscription {
2030 status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2031 bump_stamp: None,
2032 },
2033 StoredThreadSubscription {
2034 status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2035 bump_stamp: Some(1101),
2036 },
2037 StoredThreadSubscription {
2038 status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2039 bump_stamp: Some(222),
2040 },
2041 StoredThreadSubscription {
2042 status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2043 bump_stamp: Some(1),
2044 },
2045 StoredThreadSubscription {
2046 status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2047 bump_stamp: Some(100),
2048 },
2049 ]);
2050
2051 let expected_subscriptions = build_subscription_updates(&[
2052 StoredThreadSubscription {
2054 status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2055 bump_stamp: None,
2056 },
2057 StoredThreadSubscription {
2059 status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2060 bump_stamp: Some(14),
2061 },
2062 StoredThreadSubscription {
2064 status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2065 bump_stamp: Some(1101),
2066 },
2067 StoredThreadSubscription {
2069 status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2070 bump_stamp: Some(222),
2071 },
2072 StoredThreadSubscription {
2074 status: ThreadSubscriptionStatus::Unsubscribed,
2075 bump_stamp: Some(5),
2076 },
2077 StoredThreadSubscription {
2079 status: ThreadSubscriptionStatus::Unsubscribed,
2080 bump_stamp: Some(100),
2081 },
2082 ]);
2083
2084 self.upsert_thread_subscriptions(initial_subscriptions.clone()).await?;
2086
2087 for (room_id, thread_id, expected_sub) in &initial_subscriptions {
2089 let stored_subscription = self.load_thread_subscription(room_id, thread_id).await?;
2090 assert_eq!(stored_subscription, Some(*expected_sub));
2091 }
2092
2093 self.upsert_thread_subscriptions(update_subscriptions).await?;
2095
2096 for (room_id, thread_id, expected_sub) in &expected_subscriptions {
2098 let stored_subscription = self.load_thread_subscription(room_id, thread_id).await?;
2099 assert_eq!(stored_subscription, Some(*expected_sub));
2100 }
2101
2102 for (room_id, thread_id, _) in &expected_subscriptions {
2104 self.remove_thread_subscription(room_id, thread_id).await?;
2105 }
2106
2107 let initial_subscriptions = build_subscription_updates(&[
2108 StoredThreadSubscription {
2109 status: ThreadSubscriptionStatus::Unsubscribed,
2110 bump_stamp: Some(1),
2111 },
2112 StoredThreadSubscription {
2113 status: ThreadSubscriptionStatus::Subscribed { automatic: false },
2114 bump_stamp: Some(1),
2115 },
2116 StoredThreadSubscription {
2117 status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2118 bump_stamp: Some(1),
2119 },
2120 ]);
2121
2122 self.upsert_thread_subscriptions(initial_subscriptions.clone()).await?;
2123
2124 for (room_id, thread_id, expected_sub) in &initial_subscriptions {
2125 let stored_subscription = self.load_thread_subscription(room_id, thread_id).await?;
2126 assert_eq!(stored_subscription, Some(*expected_sub));
2127 }
2128
2129 let update_subscriptions = build_subscription_updates(&[
2130 StoredThreadSubscription {
2131 status: ThreadSubscriptionStatus::Subscribed { automatic: true },
2132 bump_stamp: Some(2),
2133 },
2134 StoredThreadSubscription {
2135 status: ThreadSubscriptionStatus::Unsubscribed,
2136 bump_stamp: Some(2),
2137 },
2138 StoredThreadSubscription {
2139 status: ThreadSubscriptionStatus::Subscribed { automatic: false },
2140 bump_stamp: Some(2),
2141 },
2142 ]);
2143
2144 self.upsert_thread_subscriptions(update_subscriptions.clone()).await?;
2145
2146 for (room_id, thread_id, expected_sub) in &update_subscriptions {
2147 let stored_subscription = self.load_thread_subscription(room_id, thread_id).await?;
2148 assert_eq!(stored_subscription, Some(*expected_sub));
2149 }
2150
2151 Ok(())
2152 }
2153
2154 async fn test_global_profiles_saving(&self) -> TestResult {
2155 let user_id = user_id();
2156
2157 assert_matches!(self.get_global_profile(user_id).await, Ok(None));
2158
2159 let mut fields = BTreeMap::new();
2160 fields.insert("displayname".to_owned(), json!("Alice"));
2161 fields.insert("avatar_url".to_owned(), json!(null));
2162 let update = UserProfileUpdate::from_iter(fields);
2163
2164 let mut changes = StateChanges::default();
2165 changes.global_profiles.insert(user_id.to_owned(), update);
2166 self.save_changes(&changes).await?;
2167
2168 let loaded = self.get_global_profile(user_id).await?.expect("Profile should be saved");
2169 let loaded_map: BTreeMap<String, serde_json::Value> = loaded.into_iter().collect();
2170 assert_eq!(loaded_map.get("displayname"), Some(&json!("Alice")));
2171 assert!(!loaded_map.contains_key("avatar_url"));
2172
2173 let mut fields = BTreeMap::new();
2174 fields.insert("displayname".to_owned(), json!(null));
2175 fields.insert("avatar_url".to_owned(), json!("mxc://example.com/avatar"));
2176 let update2 = UserProfileUpdate::from_iter(fields);
2177
2178 let mut changes = StateChanges::default();
2179 changes.global_profiles.insert(user_id.to_owned(), update2);
2180 self.save_changes(&changes).await?;
2181
2182 let loaded2 = self.get_global_profile(user_id).await?.expect("Profile should exist");
2183 let loaded_map2: BTreeMap<String, serde_json::Value> = loaded2.into_iter().collect();
2184 assert!(!loaded_map2.contains_key("displayname"));
2185 assert_eq!(loaded_map2.get("avatar_url"), Some(&json!("mxc://example.com/avatar")));
2186
2187 Ok(())
2188 }
2189
2190 async fn test_global_profiles_bulk_loading(&self) -> TestResult {
2191 let alice = user_id!("@alice:localhost");
2192 let bob = user_id!("@bob:localhost");
2193 let unknown = user_id!("@unknown:localhost");
2194
2195 let mut changes = StateChanges::default();
2196 changes.global_profiles.insert(
2197 alice.to_owned(),
2198 UserProfileUpdate::from_iter([("displayname".to_owned(), json!("Alice"))]),
2199 );
2200 changes.global_profiles.insert(
2201 bob.to_owned(),
2202 UserProfileUpdate::from_iter([("displayname".to_owned(), json!("Bob"))]),
2203 );
2204 self.save_changes(&changes).await?;
2205
2206 let requested = [alice.to_owned(), bob.to_owned(), unknown.to_owned()];
2208 let profiles = self.get_global_profiles(&requested).await?;
2209
2210 assert_eq!(profiles.len(), 2);
2211 assert!(!profiles.contains_key(unknown));
2212
2213 let alice_map: BTreeMap<String, serde_json::Value> = profiles
2214 .get(alice)
2215 .expect("Alice's profile should be loaded")
2216 .clone()
2217 .into_iter()
2218 .collect();
2219 assert_eq!(alice_map.get("displayname"), Some(&json!("Alice")));
2220
2221 let bob_map: BTreeMap<String, serde_json::Value> = profiles
2222 .get(bob)
2223 .expect("Bob's profile should be loaded")
2224 .clone()
2225 .into_iter()
2226 .collect();
2227 assert_eq!(bob_map.get("displayname"), Some(&json!("Bob")));
2228
2229 Ok(())
2230 }
2231}
2232
2233#[allow(unused_macros, unused_extern_crates)]
2259#[macro_export]
2260macro_rules! statestore_integration_tests {
2261 () => {
2262 mod statestore_integration_tests {
2263 use matrix_sdk_test::{TestResult, async_test};
2264 use $crate::store::{IntoStateStore, StateStoreIntegrationTests};
2265
2266 use super::get_store;
2267
2268 #[async_test]
2269 async fn test_topic_redaction() -> TestResult {
2270 let store = get_store().await?.into_state_store();
2271 store.test_topic_redaction().await
2272 }
2273
2274 #[async_test]
2275 async fn test_populate_store() -> TestResult {
2276 let store = get_store().await?.into_state_store();
2277 store.test_populate_store().await
2278 }
2279
2280 #[async_test]
2281 async fn test_member_saving() -> TestResult {
2282 let store = get_store().await?.into_state_store();
2283 store.test_member_saving().await
2284 }
2285
2286 #[async_test]
2287 async fn test_filter_saving() -> TestResult {
2288 let store = get_store().await?.into_state_store();
2289 store.test_filter_saving().await
2290 }
2291
2292 #[async_test]
2293 async fn test_user_avatar_url_saving() -> TestResult {
2294 let store = get_store().await?.into_state_store();
2295 store.test_user_avatar_url_saving().await
2296 }
2297
2298 #[async_test]
2299 async fn test_supported_versions_saving() -> TestResult {
2300 let store = get_store().await?.into_state_store();
2301 store.test_supported_versions_saving().await
2302 }
2303
2304 #[async_test]
2305 async fn test_well_known_saving() -> TestResult {
2306 let store = get_store().await?.into_state_store();
2307 store.test_well_known_saving().await
2308 }
2309
2310 #[async_test]
2311 async fn test_sync_token_saving() -> TestResult {
2312 let store = get_store().await?.into_state_store();
2313 store.test_sync_token_saving().await
2314 }
2315
2316 #[async_test]
2317 async fn test_utd_hook_manager_data_saving() -> TestResult {
2318 let store = get_store().await?.into_state_store();
2319 store.test_utd_hook_manager_data_saving().await
2320 }
2321
2322 #[async_test]
2323 async fn test_one_time_key_already_uploaded_data_saving() -> TestResult {
2324 let store = get_store().await?.into_state_store();
2325 store.test_one_time_key_already_uploaded_data_saving().await
2326 }
2327
2328 #[async_test]
2329 async fn test_stripped_member_saving() -> TestResult {
2330 let store = get_store().await?.into_state_store();
2331 store.test_stripped_member_saving().await
2332 }
2333
2334 #[async_test]
2335 async fn test_power_level_saving() -> TestResult {
2336 let store = get_store().await?.into_state_store();
2337 store.test_power_level_saving().await
2338 }
2339
2340 #[async_test]
2341 async fn test_receipts_saving() -> TestResult {
2342 let store = get_store().await?.into_state_store();
2343 store.test_receipts_saving().await
2344 }
2345
2346 #[async_test]
2347 async fn test_custom_storage() -> TestResult {
2348 let store = get_store().await?.into_state_store();
2349 store.test_custom_storage().await
2350 }
2351
2352 #[async_test]
2353 async fn test_stripped_non_stripped() -> TestResult {
2354 let store = get_store().await?.into_state_store();
2355 store.test_stripped_non_stripped().await
2356 }
2357
2358 #[async_test]
2359 async fn test_room_removal() -> TestResult {
2360 let store = get_store().await?.into_state_store();
2361 store.test_room_removal().await
2362 }
2363
2364 #[async_test]
2365 async fn test_profile_removal() -> TestResult {
2366 let store = get_store().await?.into_state_store();
2367 store.test_profile_removal().await
2368 }
2369
2370 #[async_test]
2371 async fn test_presence_saving() -> TestResult {
2372 let store = get_store().await?.into_state_store();
2373 store.test_presence_saving().await
2374 }
2375
2376 #[async_test]
2377 async fn test_display_names_saving() -> TestResult {
2378 let store = get_store().await?.into_state_store();
2379 store.test_display_names_saving().await
2380 }
2381
2382 #[async_test]
2383 async fn test_send_queue() -> TestResult {
2384 let store = get_store().await?.into_state_store();
2385 store.test_send_queue().await
2386 }
2387
2388 #[async_test]
2389 async fn test_send_queue_priority() -> TestResult {
2390 let store = get_store().await?.into_state_store();
2391 store.test_send_queue_priority().await
2392 }
2393
2394 #[async_test]
2395 async fn test_send_queue_dependents() -> TestResult {
2396 let store = get_store().await?.into_state_store();
2397 store.test_send_queue_dependents().await
2398 }
2399
2400 #[async_test]
2401 async fn test_update_send_queue_dependent() -> TestResult {
2402 let store = get_store().await?.into_state_store();
2403 store.test_update_send_queue_dependent().await
2404 }
2405
2406 #[async_test]
2407 async fn test_get_room_infos() -> TestResult {
2408 let store = get_store().await?.into_state_store();
2409 store.test_get_room_infos().await
2410 }
2411
2412 #[async_test]
2413 async fn test_thread_subscriptions() -> TestResult {
2414 let store = get_store().await?.into_state_store();
2415 store.test_thread_subscriptions().await
2416 }
2417
2418 #[async_test]
2419 async fn test_thread_subscriptions_bulk_upsert() -> TestResult {
2420 let store = get_store().await?.into_state_store();
2421 store.test_thread_subscriptions_bulk_upsert().await
2422 }
2423
2424 #[async_test]
2425 async fn test_global_profiles_saving() -> TestResult {
2426 let store = get_store().await?.into_state_store();
2427 store.test_global_profiles_saving().await
2428 }
2429
2430 #[async_test]
2431 async fn test_global_profiles_bulk_loading() -> TestResult {
2432 let store = get_store().await?.into_state_store();
2433 store.test_global_profiles_bulk_loading().await
2434 }
2435 }
2436 };
2437}
2438
2439fn user_id() -> &'static UserId {
2440 user_id!("@example:localhost")
2441}
2442
2443fn invited_user_id() -> &'static UserId {
2444 user_id!("@invited:localhost")
2445}
2446
2447fn room_id() -> &'static RoomId {
2448 room_id!("!test:localhost")
2449}
2450
2451fn stripped_room_id() -> &'static RoomId {
2452 room_id!("!stripped:localhost")
2453}
2454
2455fn first_receipt_event_id() -> &'static EventId {
2456 event_id!("$example")
2457}
2458
2459fn topic_event_id() -> &'static EventId {
2460 event_id!("$topic_event")
2461}
2462
2463fn power_level_event() -> Raw<AnySyncStateEvent> {
2464 let content = RoomPowerLevelsEventContent::new(&AuthorizationRules::V1);
2465
2466 let event = json!({
2467 "event_id": "$h29iv0s8:example.com",
2468 "content": content,
2469 "sender": user_id(),
2470 "type": "m.room.power_levels",
2471 "origin_server_ts": 0u64,
2472 "state_key": "",
2473 });
2474
2475 serde_json::from_value(event).unwrap()
2476}
2477
2478fn stripped_membership_event() -> Raw<StrippedRoomMemberEvent> {
2479 custom_stripped_membership_event(user_id())
2480}
2481
2482fn custom_stripped_membership_event(user_id: &UserId) -> Raw<StrippedRoomMemberEvent> {
2483 let ev_json = json!({
2484 "type": "m.room.member",
2485 "content": RoomMemberEventContent::new(MembershipState::Join),
2486 "sender": user_id,
2487 "state_key": user_id,
2488 });
2489
2490 Raw::new(&ev_json).unwrap().cast_unchecked()
2491}
2492
2493fn membership_event() -> Raw<SyncRoomMemberEvent> {
2494 custom_membership_event(user_id(), event_id!("$h29iv0s8:example.com"))
2495}
2496
2497fn custom_membership_event(user_id: &UserId, event_id: &EventId) -> Raw<SyncRoomMemberEvent> {
2498 let ev_json = json!({
2499 "type": "m.room.member",
2500 "content": RoomMemberEventContent::new(MembershipState::Join),
2501 "event_id": event_id,
2502 "origin_server_ts": 198,
2503 "sender": user_id,
2504 "state_key": user_id,
2505 });
2506
2507 Raw::new(&ev_json).unwrap().cast_unchecked()
2508}
2509
2510fn custom_presence_event(user_id: &UserId) -> Raw<PresenceEvent> {
2511 let ev_json = json!({
2512 "content": {
2513 "presence": "online"
2514 },
2515 "sender": user_id,
2516 });
2517
2518 Raw::new(&ev_json).unwrap().cast_unchecked()
2519}