1use 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#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
51#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
52pub trait StateStoreIntegrationTests {
53 async fn populate(&self) -> Result<()>;
55 async fn test_topic_redaction(&self) -> Result<()>;
57 async fn test_populate_store(&self) -> Result<()>;
59 async fn test_member_saving(&self);
61 async fn test_filter_saving(&self);
63 async fn test_user_avatar_url_saving(&self);
65 async fn test_sync_token_saving(&self);
67 async fn test_utd_hook_manager_data_saving(&self);
69 async fn test_stripped_member_saving(&self);
71 async fn test_power_level_saving(&self);
73 async fn test_receipts_saving(&self);
75 async fn test_custom_storage(&self) -> Result<()>;
77 async fn test_stripped_non_stripped(&self) -> Result<()>;
79 async fn test_room_removal(&self) -> Result<()>;
81 async fn test_profile_removal(&self) -> Result<()>;
83 async fn test_presence_saving(&self);
85 async fn test_display_names_saving(&self);
87 async fn test_send_queue(&self);
89 async fn test_send_queue_priority(&self);
91 async fn test_send_queue_dependents(&self);
93 async fn test_update_send_queue_dependent(&self);
95 async fn test_server_capabilities_saving(&self);
97 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 profiles_to_delete: [(
1103 room_id.to_owned(),
1104 vec![user_id.to_owned(), invited_user_id.to_owned()],
1105 )]
1106 .into(),
1107
1108 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 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 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 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 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 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 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 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 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 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 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 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 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 let events = self.load_send_queue_requests(room_id).await.unwrap();
1257 assert!(events.is_empty());
1258
1259 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 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 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 let pending = self.load_send_queue_requests(room_id).await.unwrap();
1309
1310 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 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 let pending = self.load_send_queue_requests(room_id).await.unwrap();
1334
1335 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 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 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 self.remove_send_queue_request(room_id, &txn0).await.unwrap();
1382
1383 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 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 {
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 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 let events = self.load_send_queue_requests(room_id).await.unwrap();
1446 assert!(events.is_empty());
1447
1448 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 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 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 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 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 assert!(self.load_dependent_queued_requests(room_id).await.unwrap().is_empty());
1543
1544 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 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 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 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 let removed = self
1588 .remove_dependent_queued_request(room_id, &dependents[0].own_transaction_id)
1589 .await
1590 .unwrap();
1591 assert!(removed);
1592
1593 assert!(self.load_dependent_queued_requests(room_id).await.unwrap().is_empty());
1595
1596 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 let removed = self.remove_send_queue_request(room_id, &txn0).await.unwrap();
1641 assert!(removed);
1642
1643 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 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 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 self.update_dependent_queued_request(
1676 room_id,
1677 &child_txn,
1678 DependentQueuedRequestKind::ReactEvent { key: "👍".to_owned() },
1679 )
1680 .await
1681 .unwrap();
1682
1683 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 {
1704 assert_eq!(self.get_room_infos(&RoomLoadSettings::default()).await.unwrap().len(), 0);
1705 }
1706
1707 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 {
1715 let mut all_rooms = self.get_room_infos(&RoomLoadSettings::All).await.unwrap();
1716
1717 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 {
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 {
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#[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}