1use std::sync::Arc;
18
19use indexmap::IndexSet;
20use ruma::{
21 api::client::push::{
22 delete_pushrule, set_pushrule, set_pushrule_actions, set_pushrule_enabled,
23 },
24 events::push_rules::PushRulesEvent,
25 push::{Action, PredefinedUnderrideRuleId, RuleKind, Ruleset, Tweak},
26 RoomId,
27};
28use tokio::sync::{
29 broadcast::{self, Receiver},
30 RwLock,
31};
32use tracing::{debug, error};
33
34use self::{command::Command, rule_commands::RuleCommands, rules::Rules};
35
36mod command;
37mod rule_commands;
38mod rules;
39
40pub use matrix_sdk_base::notification_settings::RoomNotificationMode;
41
42use crate::{
43 config::RequestConfig, error::NotificationSettingsError, event_handler::EventHandlerDropGuard,
44 Client, Result,
45};
46
47#[derive(Debug, Clone, Copy)]
49pub enum IsEncrypted {
50 Yes,
52 No,
54}
55
56impl From<bool> for IsEncrypted {
57 fn from(value: bool) -> Self {
58 if value {
59 Self::Yes
60 } else {
61 Self::No
62 }
63 }
64}
65
66#[derive(Debug, Clone, Copy)]
68pub enum IsOneToOne {
69 Yes,
71 No,
73}
74
75impl From<bool> for IsOneToOne {
76 fn from(value: bool) -> Self {
77 if value {
78 Self::Yes
79 } else {
80 Self::No
81 }
82 }
83}
84
85#[derive(Debug, Clone)]
87pub struct NotificationSettings {
88 client: Client,
90 rules: Arc<RwLock<Rules>>,
92 _push_rules_event_handler_guard: Arc<EventHandlerDropGuard>,
94 changes_sender: broadcast::Sender<()>,
95}
96
97impl NotificationSettings {
98 pub(crate) fn new(client: Client, ruleset: Ruleset) -> Self {
105 let changes_sender = broadcast::Sender::new(100);
106 let rules = Arc::new(RwLock::new(Rules::new(ruleset)));
107
108 let push_rules_event_handler_handle = client.add_event_handler({
110 let changes_sender = changes_sender.clone();
111 let rules = Arc::clone(&rules);
112 move |ev: PushRulesEvent| async move {
113 *rules.write().await = Rules::new(ev.content.global);
114 let _ = changes_sender.send(());
115 }
116 });
117 let _push_rules_event_handler_guard =
118 client.event_handler_drop_guard(push_rules_event_handler_handle).into();
119
120 Self { client, rules, _push_rules_event_handler_guard, changes_sender }
121 }
122
123 pub fn subscribe_to_changes(&self) -> Receiver<()> {
127 self.changes_sender.subscribe()
128 }
129
130 pub async fn get_user_defined_room_notification_mode(
132 &self,
133 room_id: &RoomId,
134 ) -> Option<RoomNotificationMode> {
135 self.rules.read().await.get_user_defined_room_notification_mode(room_id)
136 }
137
138 pub async fn get_default_room_notification_mode(
146 &self,
147 is_encrypted: IsEncrypted,
148 is_one_to_one: IsOneToOne,
149 ) -> RoomNotificationMode {
150 self.rules.read().await.get_default_room_notification_mode(is_encrypted, is_one_to_one)
151 }
152
153 pub async fn get_rooms_with_user_defined_rules(&self, enabled: Option<bool>) -> Vec<String> {
155 self.rules.read().await.get_rooms_with_user_defined_rules(enabled)
156 }
157
158 pub async fn contains_keyword_rules(&self) -> bool {
160 self.rules.read().await.contains_keyword_rules()
161 }
162
163 pub async fn is_push_rule_enabled(
165 &self,
166 kind: RuleKind,
167 rule_id: impl AsRef<str>,
168 ) -> Result<bool, NotificationSettingsError> {
169 self.rules.read().await.is_enabled(kind, rule_id.as_ref())
170 }
171
172 pub async fn set_push_rule_enabled(
174 &self,
175 kind: RuleKind,
176 rule_id: impl AsRef<str>,
177 enabled: bool,
178 ) -> Result<(), NotificationSettingsError> {
179 let rules = self.rules.read().await.clone();
180
181 let mut rule_commands = RuleCommands::new(rules.ruleset);
182 rule_commands.set_rule_enabled(kind, rule_id.as_ref(), enabled)?;
183
184 self.run_server_commands(&rule_commands).await?;
185
186 let rules = &mut *self.rules.write().await;
187 rules.apply(rule_commands);
188
189 Ok(())
190 }
191
192 pub async fn set_default_room_notification_mode(
201 &self,
202 is_encrypted: IsEncrypted,
203 is_one_to_one: IsOneToOne,
204 mode: RoomNotificationMode,
205 ) -> Result<(), NotificationSettingsError> {
206 let actions = match mode {
207 RoomNotificationMode::AllMessages => {
208 vec![Action::Notify, Action::SetTweak(Tweak::Sound("default".into()))]
209 }
210 _ => {
211 vec![]
212 }
213 };
214
215 let room_rule_id =
216 rules::get_predefined_underride_room_rule_id(is_encrypted, is_one_to_one);
217 self.set_underride_push_rule_actions(room_rule_id, actions.clone()).await?;
218
219 let poll_start_rule_id = rules::get_predefined_underride_poll_start_rule_id(is_one_to_one);
220 if let Err(error) =
221 self.set_underride_push_rule_actions(poll_start_rule_id, actions.clone()).await
222 {
223 if let NotificationSettingsError::RuleNotFound(rule_id) = &error {
226 debug!("Unable to update poll start push rule: rule `{rule_id}` not found");
227 } else {
228 return Err(error);
229 }
230 }
231
232 Ok(())
233 }
234
235 pub async fn set_underride_push_rule_actions(
246 &self,
247 rule_id: PredefinedUnderrideRuleId,
248 actions: Vec<Action>,
249 ) -> Result<(), NotificationSettingsError> {
250 let rules = self.rules.read().await.clone();
251 let rule_kind = RuleKind::Underride;
252 let mut rule_commands = RuleCommands::new(rules.clone().ruleset);
253
254 rule_commands.set_rule_actions(rule_kind.clone(), rule_id.as_str(), actions)?;
255
256 if !rules.is_enabled(rule_kind.clone(), rule_id.as_str())? {
257 rule_commands.set_rule_enabled(rule_kind, rule_id.as_str(), true)?
258 }
259
260 self.run_server_commands(&rule_commands).await?;
261
262 let rules = &mut *self.rules.write().await;
263 rules.apply(rule_commands);
264
265 Ok(())
266 }
267
268 pub async fn set_room_notification_mode(
270 &self,
271 room_id: &RoomId,
272 mode: RoomNotificationMode,
273 ) -> Result<(), NotificationSettingsError> {
274 let rules = self.rules.read().await.clone();
275
276 if rules.get_user_defined_room_notification_mode(room_id) == Some(mode) {
278 return Ok(());
279 }
280
281 let (new_rule_kind, notify) = match mode {
283 RoomNotificationMode::AllMessages => {
284 (RuleKind::Room, true)
286 }
287 RoomNotificationMode::MentionsAndKeywordsOnly => {
288 (RuleKind::Room, false)
290 }
291 RoomNotificationMode::Mute => {
292 (RuleKind::Override, false)
294 }
295 };
296
297 let new_rule_id = room_id.as_str();
299 let custom_rules: Vec<(RuleKind, String)> = rules
300 .get_custom_rules_for_room(room_id)
301 .into_iter()
302 .filter(|(kind, rule_id)| kind != &new_rule_kind || rule_id != new_rule_id)
303 .collect();
304
305 let mut rule_commands = RuleCommands::new(rules.ruleset);
308 rule_commands.insert_rule(new_rule_kind.clone(), room_id, notify)?;
309 for (kind, rule_id) in custom_rules {
310 rule_commands.delete_rule(kind, rule_id)?;
311 }
312
313 self.run_server_commands(&rule_commands).await?;
314
315 let rules = &mut *self.rules.write().await;
316 rules.apply(rule_commands);
317
318 Ok(())
319 }
320
321 pub async fn delete_user_defined_room_rules(
323 &self,
324 room_id: &RoomId,
325 ) -> Result<(), NotificationSettingsError> {
326 let rules = self.rules.read().await.clone();
327
328 let custom_rules = rules.get_custom_rules_for_room(room_id);
329 if custom_rules.is_empty() {
330 return Ok(());
331 }
332
333 let mut rule_commands = RuleCommands::new(rules.ruleset);
334 for (kind, rule_id) in custom_rules {
335 rule_commands.delete_rule(kind, rule_id)?;
336 }
337
338 self.run_server_commands(&rule_commands).await?;
339
340 let rules = &mut *self.rules.write().await;
341 rules.apply(rule_commands);
342
343 Ok(())
344 }
345
346 pub async fn unmute_room(
348 &self,
349 room_id: &RoomId,
350 is_encrypted: IsEncrypted,
351 is_one_to_one: IsOneToOne,
352 ) -> Result<(), NotificationSettingsError> {
353 let rules = self.rules.read().await.clone();
354
355 if let Some(room_mode) = rules.get_user_defined_room_notification_mode(room_id) {
357 if room_mode != RoomNotificationMode::Mute {
358 return Ok(());
360 }
361
362 let default_mode =
364 rules.get_default_room_notification_mode(is_encrypted, is_one_to_one);
365
366 if default_mode == RoomNotificationMode::Mute {
368 self.set_room_notification_mode(room_id, RoomNotificationMode::AllMessages).await
369 } else {
370 self.delete_user_defined_room_rules(room_id).await
372 }
373 } else {
374 self.set_room_notification_mode(room_id, RoomNotificationMode::AllMessages).await
377 }
378 }
379
380 pub async fn enabled_keywords(&self) -> IndexSet<String> {
382 self.rules.read().await.enabled_keywords()
383 }
384
385 pub async fn add_keyword(&self, keyword: String) -> Result<(), NotificationSettingsError> {
391 let rules = self.rules.read().await.clone();
392
393 let mut rule_commands = RuleCommands::new(rules.clone().ruleset);
394
395 let existing_rules = rules.keyword_rules(&keyword);
396
397 if existing_rules.is_empty() {
398 rule_commands.insert_keyword_rule(keyword)?;
400 } else {
401 if existing_rules.iter().any(|r| r.enabled) {
402 return Ok(());
404 }
405
406 rule_commands.set_rule_enabled(RuleKind::Content, &existing_rules[0].rule_id, true)?;
408 }
409
410 self.run_server_commands(&rule_commands).await?;
411
412 let rules = &mut *self.rules.write().await;
413 rules.apply(rule_commands);
414
415 Ok(())
416 }
417
418 pub async fn remove_keyword(&self, keyword: &str) -> Result<(), NotificationSettingsError> {
424 let rules = self.rules.read().await.clone();
425
426 let mut rule_commands = RuleCommands::new(rules.clone().ruleset);
427
428 let existing_rules = rules.keyword_rules(keyword);
429
430 if existing_rules.is_empty() {
431 return Ok(());
432 }
433
434 for rule in existing_rules {
435 rule_commands.delete_rule(RuleKind::Content, rule.rule_id.clone())?;
436 }
437
438 self.run_server_commands(&rule_commands).await?;
439
440 let rules = &mut *self.rules.write().await;
441 rules.apply(rule_commands);
442
443 Ok(())
444 }
445
446 async fn run_server_commands(
448 &self,
449 rule_commands: &RuleCommands,
450 ) -> Result<(), NotificationSettingsError> {
451 let request_config = Some(RequestConfig::short_retry());
452 for command in &rule_commands.commands {
453 match command {
454 Command::DeletePushRule { kind, rule_id } => {
455 let request = delete_pushrule::v3::Request::new(kind.clone(), rule_id.clone());
456 self.client.send(request).with_request_config(request_config).await.map_err(
457 |error| {
458 error!("Unable to delete {kind} push rule `{rule_id}`: {error}");
459 NotificationSettingsError::UnableToRemovePushRule
460 },
461 )?;
462 }
463 Command::SetRoomPushRule { room_id, notify: _ } => {
464 let push_rule = command.to_push_rule()?;
465 let request = set_pushrule::v3::Request::new(push_rule);
466 self.client.send(request).with_request_config(request_config).await.map_err(
467 |error| {
468 error!("Unable to set room push rule `{room_id}`: {error}");
469 NotificationSettingsError::UnableToAddPushRule
470 },
471 )?;
472 }
473 Command::SetOverridePushRule { rule_id, room_id: _, notify: _ } => {
474 let push_rule = command.to_push_rule()?;
475 let request = set_pushrule::v3::Request::new(push_rule);
476 self.client.send(request).with_request_config(request_config).await.map_err(
477 |error| {
478 error!("Unable to set override push rule `{rule_id}`: {error}");
479 NotificationSettingsError::UnableToAddPushRule
480 },
481 )?;
482 }
483 Command::SetKeywordPushRule { keyword: _ } => {
484 let push_rule = command.to_push_rule()?;
485 let request = set_pushrule::v3::Request::new(push_rule);
486 self.client
487 .send(request)
488 .with_request_config(request_config)
489 .await
490 .map_err(|_| NotificationSettingsError::UnableToAddPushRule)?;
491 }
492 Command::SetPushRuleEnabled { kind, rule_id, enabled } => {
493 let request = set_pushrule_enabled::v3::Request::new(
494 kind.clone(),
495 rule_id.clone(),
496 *enabled,
497 );
498 self.client.send(request).with_request_config(request_config).await.map_err(
499 |error| {
500 error!("Unable to set {kind} push rule `{rule_id}` enabled: {error}");
501 NotificationSettingsError::UnableToUpdatePushRule
502 },
503 )?;
504 }
505 Command::SetPushRuleActions { kind, rule_id, actions } => {
506 let request = set_pushrule_actions::v3::Request::new(
507 kind.clone(),
508 rule_id.clone(),
509 actions.clone(),
510 );
511 self.client.send(request).with_request_config(request_config).await.map_err(
512 |error| {
513 error!("Unable to set {kind} push rule `{rule_id}` actions: {error}");
514 NotificationSettingsError::UnableToUpdatePushRule
515 },
516 )?;
517 }
518 }
519 }
520 Ok(())
521 }
522}
523
524#[cfg(all(test, not(target_arch = "wasm32")))]
526mod tests {
527 use std::sync::{
528 atomic::{AtomicBool, Ordering},
529 Arc,
530 };
531
532 use assert_matches::assert_matches;
533 use matrix_sdk_test::{
534 async_test,
535 notification_settings::{build_ruleset, get_server_default_ruleset},
536 test_json,
537 };
538 use ruma::{
539 push::{
540 Action, AnyPushRuleRef, NewPatternedPushRule, NewPushRule, PredefinedOverrideRuleId,
541 PredefinedUnderrideRuleId, RuleKind,
542 },
543 OwnedRoomId, RoomId,
544 };
545 use serde_json::json;
546 use stream_assert::{assert_next_eq, assert_pending};
547 use tokio_stream::wrappers::BroadcastStream;
548 use wiremock::{
549 matchers::{header, method, path, path_regex},
550 Mock, MockServer, ResponseTemplate,
551 };
552
553 use crate::{
554 config::SyncSettings,
555 error::NotificationSettingsError,
556 notification_settings::{
557 IsEncrypted, IsOneToOne, NotificationSettings, RoomNotificationMode,
558 },
559 test_utils::logged_in_client,
560 Client,
561 };
562
563 fn get_test_room_id() -> OwnedRoomId {
564 RoomId::parse("!AAAaAAAAAaaAAaaaaa:matrix.org").unwrap()
565 }
566
567 fn from_insert_rules(
568 client: &Client,
569 rules: Vec<(RuleKind, &RoomId, bool)>,
570 ) -> NotificationSettings {
571 let ruleset = build_ruleset(rules);
572 NotificationSettings::new(client.to_owned(), ruleset)
573 }
574
575 async fn get_custom_rules_for_room(
576 settings: &NotificationSettings,
577 room_id: &RoomId,
578 ) -> Vec<(RuleKind, String)> {
579 settings.rules.read().await.get_custom_rules_for_room(room_id)
580 }
581
582 #[async_test]
583 async fn test_subscribe_to_changes() {
584 let server = MockServer::start().await;
585 let client = logged_in_client(Some(server.uri())).await;
586 let settings = client.notification_settings().await;
587
588 Mock::given(method("GET"))
589 .and(path("/_matrix/client/r0/sync"))
590 .and(header("authorization", "Bearer 1234"))
591 .respond_with(ResponseTemplate::new(200).set_body_json(json!({
592 "next_batch": "1234",
593 "account_data": {
594 "events": [*test_json::PUSH_RULES]
595 }
596 })))
597 .expect(1)
598 .mount(&server)
599 .await;
600
601 let subscriber = settings.subscribe_to_changes();
602 let mut stream = BroadcastStream::new(subscriber);
603
604 assert_pending!(stream);
605
606 client.sync_once(SyncSettings::default()).await.unwrap();
607
608 assert_next_eq!(stream, Ok(()));
609 assert_pending!(stream);
610 }
611
612 #[async_test]
613 async fn test_get_custom_rules_for_room() {
614 let server = MockServer::start().await;
615 let client = logged_in_client(Some(server.uri())).await;
616 let room_id = get_test_room_id();
617
618 let settings = from_insert_rules(&client, vec![(RuleKind::Room, &room_id, true)]);
619
620 let custom_rules = get_custom_rules_for_room(&settings, &room_id).await;
621 assert_eq!(custom_rules.len(), 1);
622 assert_eq!(custom_rules[0], (RuleKind::Room, room_id.to_string()));
623
624 let settings = from_insert_rules(
625 &client,
626 vec![(RuleKind::Room, &room_id, true), (RuleKind::Override, &room_id, true)],
627 );
628 let custom_rules = get_custom_rules_for_room(&settings, &room_id).await;
629 assert_eq!(custom_rules.len(), 2);
630 assert_eq!(custom_rules[0], (RuleKind::Override, room_id.to_string()));
631 assert_eq!(custom_rules[1], (RuleKind::Room, room_id.to_string()));
632 }
633
634 #[async_test]
635 async fn test_get_user_defined_room_notification_mode_none() {
636 let server = MockServer::start().await;
637 let client = logged_in_client(Some(server.uri())).await;
638 let room_id = get_test_room_id();
639
640 let settings = client.notification_settings().await;
641 assert!(settings.get_user_defined_room_notification_mode(&room_id).await.is_none());
642 }
643
644 #[async_test]
645 async fn test_get_user_defined_room_notification_mode_all_messages() {
646 let server = MockServer::start().await;
647 let client = logged_in_client(Some(server.uri())).await;
648 let room_id = get_test_room_id();
649
650 let settings = from_insert_rules(&client, vec![(RuleKind::Room, &room_id, true)]);
652
653 assert_eq!(
654 settings.get_user_defined_room_notification_mode(&room_id).await.unwrap(),
655 RoomNotificationMode::AllMessages
656 );
657 }
658
659 #[async_test]
660 async fn test_get_user_defined_room_notification_mode_mentions_and_keywords() {
661 let server = MockServer::start().await;
662 let client = logged_in_client(Some(server.uri())).await;
663 let room_id = get_test_room_id();
664
665 let settings = from_insert_rules(&client, vec![(RuleKind::Room, &room_id, false)]);
667 assert_eq!(
668 settings.get_user_defined_room_notification_mode(&room_id).await.unwrap(),
669 RoomNotificationMode::MentionsAndKeywordsOnly
670 );
671 }
672
673 #[async_test]
674 async fn test_get_user_defined_room_notification_mode_mute() {
675 let server = MockServer::start().await;
676 let client = logged_in_client(Some(server.uri())).await;
677 let room_id = get_test_room_id();
678
679 let settings = from_insert_rules(&client, vec![(RuleKind::Override, &room_id, false)]);
681 assert_eq!(
682 settings.get_user_defined_room_notification_mode(&room_id).await.unwrap(),
683 RoomNotificationMode::Mute
684 );
685 }
686
687 #[async_test]
688 async fn test_get_default_room_notification_mode_all_messages() {
689 let server = MockServer::start().await;
690 let client = logged_in_client(Some(server.uri())).await;
691
692 let mut ruleset = get_server_default_ruleset();
693 ruleset
694 .set_actions(
695 RuleKind::Underride,
696 PredefinedUnderrideRuleId::RoomOneToOne,
697 vec![Action::Notify],
698 )
699 .unwrap();
700
701 let settings = NotificationSettings::new(client, ruleset);
702 assert_eq!(
703 settings.get_default_room_notification_mode(IsEncrypted::No, IsOneToOne::Yes).await,
704 RoomNotificationMode::AllMessages
705 );
706 }
707
708 #[async_test]
709 async fn test_get_default_room_notification_mode_mentions_and_keywords() {
710 let server = MockServer::start().await;
711 let client = logged_in_client(Some(server.uri())).await;
712
713 let mut ruleset = get_server_default_ruleset();
716 ruleset
717 .set_actions(RuleKind::Underride, PredefinedUnderrideRuleId::RoomOneToOne, vec![])
718 .unwrap();
719
720 let settings = NotificationSettings::new(client.to_owned(), ruleset.to_owned());
721 assert_eq!(
722 settings.get_default_room_notification_mode(IsEncrypted::No, IsOneToOne::Yes).await,
723 RoomNotificationMode::MentionsAndKeywordsOnly
724 );
725
726 ruleset
729 .set_enabled(RuleKind::Underride, PredefinedUnderrideRuleId::RoomOneToOne, false)
730 .unwrap();
731
732 let settings = NotificationSettings::new(client, ruleset);
733 assert_eq!(
734 settings.get_default_room_notification_mode(IsEncrypted::No, IsOneToOne::Yes).await,
735 RoomNotificationMode::MentionsAndKeywordsOnly
736 );
737 }
738
739 #[async_test]
740 async fn test_contains_keyword_rules() {
741 let server = MockServer::start().await;
742 let client = logged_in_client(Some(server.uri())).await;
743
744 let mut ruleset = get_server_default_ruleset();
745 let settings = NotificationSettings::new(client.to_owned(), ruleset.to_owned());
746
747 let contains_keywords_rules = settings.contains_keyword_rules().await;
749 assert!(!contains_keywords_rules);
750
751 let rule = NewPatternedPushRule::new(
753 "keyword_rule_id".into(),
754 "keyword".into(),
755 vec![Action::Notify],
756 );
757 ruleset.insert(NewPushRule::Content(rule), None, None).unwrap();
758
759 let settings = NotificationSettings::new(client, ruleset);
760 let contains_keywords_rules = settings.contains_keyword_rules().await;
761 assert!(contains_keywords_rules);
762 }
763
764 #[async_test]
765 async fn test_is_push_rule_enabled() {
766 let server = MockServer::start().await;
767 let client = logged_in_client(Some(server.uri())).await;
768
769 let mut ruleset = get_server_default_ruleset();
771 ruleset.set_enabled(RuleKind::Override, PredefinedOverrideRuleId::Reaction, false).unwrap();
772
773 let settings = NotificationSettings::new(client.clone(), ruleset);
774
775 let enabled = settings
776 .is_push_rule_enabled(RuleKind::Override, PredefinedOverrideRuleId::Reaction)
777 .await
778 .unwrap();
779
780 assert!(!enabled);
781
782 let mut ruleset = get_server_default_ruleset();
784 ruleset.set_enabled(RuleKind::Override, PredefinedOverrideRuleId::Reaction, true).unwrap();
785
786 let settings = NotificationSettings::new(client, ruleset);
787
788 let enabled = settings
789 .is_push_rule_enabled(RuleKind::Override, PredefinedOverrideRuleId::Reaction)
790 .await
791 .unwrap();
792
793 assert!(enabled);
794 }
795
796 #[async_test]
797 async fn test_set_push_rule_enabled() {
798 let server = MockServer::start().await;
799 let client = logged_in_client(Some(server.uri())).await;
800 let mut ruleset = client.account().push_rules().await.unwrap();
801 ruleset.set_enabled(RuleKind::Override, PredefinedOverrideRuleId::Reaction, false).unwrap();
803
804 let settings = NotificationSettings::new(client, ruleset);
805
806 Mock::given(method("PUT"))
807 .and(path("/_matrix/client/r0/pushrules/global/override/.m.rule.reaction/enabled"))
808 .respond_with(ResponseTemplate::new(200))
809 .expect(1)
810 .mount(&server)
811 .await;
812
813 settings
814 .set_push_rule_enabled(RuleKind::Override, PredefinedOverrideRuleId::Reaction, true)
815 .await
816 .unwrap();
817
818 let rules = settings.rules.read().await;
820 let rule =
821 rules.ruleset.get(RuleKind::Override, PredefinedOverrideRuleId::Reaction).unwrap();
822 assert!(rule.enabled());
823
824 server.verify().await
825 }
826
827 #[async_test]
828 async fn test_set_push_rule_enabled_api_error() {
829 let server = MockServer::start().await;
830 let client = logged_in_client(Some(server.uri())).await;
831 let mut ruleset = client.account().push_rules().await.unwrap();
832 ruleset
834 .set_enabled(RuleKind::Override, PredefinedOverrideRuleId::IsUserMention, false)
835 .unwrap();
836
837 let settings = NotificationSettings::new(client, ruleset);
838
839 Mock::given(method("PUT")).respond_with(ResponseTemplate::new(500)).mount(&server).await;
841
842 assert_eq!(
844 settings
845 .set_push_rule_enabled(
846 RuleKind::Override,
847 PredefinedOverrideRuleId::IsUserMention,
848 true,
849 )
850 .await,
851 Err(NotificationSettingsError::UnableToUpdatePushRule)
852 );
853
854 let rules = settings.rules.read().await;
856 let rule =
857 rules.ruleset.get(RuleKind::Override, PredefinedOverrideRuleId::IsUserMention).unwrap();
858 assert!(!rule.enabled());
859 }
860
861 #[async_test]
862 async fn test_set_room_notification_mode() {
863 let server = MockServer::start().await;
864 let client = logged_in_client(Some(server.uri())).await;
865
866 Mock::given(method("PUT")).respond_with(ResponseTemplate::new(200)).mount(&server).await;
867 Mock::given(method("DELETE")).respond_with(ResponseTemplate::new(200)).mount(&server).await;
868
869 let settings = client.notification_settings().await;
870 let room_id = get_test_room_id();
871
872 let mode = settings.get_user_defined_room_notification_mode(&room_id).await;
873 assert!(mode.is_none());
874
875 let new_modes = [
876 RoomNotificationMode::AllMessages,
877 RoomNotificationMode::MentionsAndKeywordsOnly,
878 RoomNotificationMode::Mute,
879 ];
880 for new_mode in new_modes {
881 settings.set_room_notification_mode(&room_id, new_mode).await.unwrap();
882
883 assert_eq!(
884 new_mode,
885 settings.get_user_defined_room_notification_mode(&room_id).await.unwrap()
886 );
887 }
888 }
889
890 #[async_test]
891 async fn test_set_room_notification_mode_requests_order() {
892 let server = MockServer::start().await;
893 let client = logged_in_client(Some(server.uri())).await;
894
895 let put_was_called = Arc::new(AtomicBool::default());
896
897 Mock::given(method("PUT"))
898 .and(path_regex(r"_matrix/client/r0/pushrules/global/override/.*"))
899 .and({
900 let put_was_called = put_was_called.clone();
901 move |_: &wiremock::Request| {
902 put_was_called.store(true, Ordering::SeqCst);
903
904 true
905 }
906 })
907 .respond_with(ResponseTemplate::new(200))
908 .expect(1)
909 .mount(&server)
910 .await;
911
912 Mock::given(method("DELETE"))
913 .and(path_regex(r"_matrix/client/r0/pushrules/global/room/.*"))
914 .and(move |_: &wiremock::Request| {
915 let put_was_called = put_was_called.load(Ordering::SeqCst);
922 assert!(
923 put_was_called,
924 "The PUT /pushrules/global/override/ method should have been called before the \
925 DELETE method"
926 );
927
928 true
929 })
930 .respond_with(ResponseTemplate::new(200))
931 .expect(1)
932 .mount(&server)
933 .await;
934
935 let room_id = get_test_room_id();
936
937 let settings = from_insert_rules(&client, vec![(RuleKind::Room, &room_id, true)]);
939
940 settings.set_room_notification_mode(&room_id, RoomNotificationMode::Mute).await.unwrap();
943
944 assert_eq!(
945 RoomNotificationMode::Mute,
946 settings.get_user_defined_room_notification_mode(&room_id).await.unwrap()
947 );
948
949 server.verify().await
950 }
951
952 #[async_test]
953 async fn test_set_room_notification_mode_put_api_error() {
954 let server = MockServer::start().await;
955 let client = logged_in_client(Some(server.uri())).await;
956
957 Mock::given(method("PUT")).respond_with(ResponseTemplate::new(500)).mount(&server).await;
959 Mock::given(method("DELETE")).respond_with(ResponseTemplate::new(200)).mount(&server).await;
960
961 let room_id = get_test_room_id();
962
963 let settings = from_insert_rules(&client, vec![(RuleKind::Room, &room_id, true)]);
965
966 assert_eq!(
967 settings.get_user_defined_room_notification_mode(&room_id).await.unwrap(),
968 RoomNotificationMode::AllMessages
969 );
970
971 assert_eq!(
973 settings.set_room_notification_mode(&room_id, RoomNotificationMode::Mute).await,
974 Err(NotificationSettingsError::UnableToAddPushRule)
975 );
976
977 assert_eq!(
979 settings.get_user_defined_room_notification_mode(&room_id).await.unwrap(),
980 RoomNotificationMode::AllMessages
981 );
982 }
983
984 #[async_test]
985 async fn test_set_room_notification_mode_delete_api_error() {
986 let server = MockServer::start().await;
987 let client = logged_in_client(Some(server.uri())).await;
988
989 Mock::given(method("PUT")).respond_with(ResponseTemplate::new(200)).mount(&server).await;
991 Mock::given(method("DELETE")).respond_with(ResponseTemplate::new(500)).mount(&server).await;
992
993 let room_id = get_test_room_id();
994
995 let settings = from_insert_rules(&client, vec![(RuleKind::Room, &room_id, true)]);
997
998 assert_eq!(
999 settings.get_user_defined_room_notification_mode(&room_id).await.unwrap(),
1000 RoomNotificationMode::AllMessages
1001 );
1002
1003 assert_eq!(
1005 settings.set_room_notification_mode(&room_id, RoomNotificationMode::Mute).await,
1006 Err(NotificationSettingsError::UnableToRemovePushRule)
1007 );
1008
1009 assert_eq!(
1011 settings.get_user_defined_room_notification_mode(&room_id).await.unwrap(),
1012 RoomNotificationMode::AllMessages
1013 );
1014 }
1015
1016 #[async_test]
1017 async fn test_delete_user_defined_room_rules() {
1018 let server = MockServer::start().await;
1019 let client = logged_in_client(Some(server.uri())).await;
1020 let room_id_a = RoomId::parse("!AAAaAAAAAaaAAaaaaa:matrix.org").unwrap();
1021 let room_id_b = RoomId::parse("!BBBbBBBBBbbBBbbbbb:matrix.org").unwrap();
1022
1023 Mock::given(method("DELETE")).respond_with(ResponseTemplate::new(200)).mount(&server).await;
1024
1025 let settings = from_insert_rules(
1027 &client,
1028 vec![
1029 (RuleKind::Room, &room_id_a, true),
1030 (RuleKind::Room, &room_id_b, true),
1031 (RuleKind::Override, &room_id_b, true),
1032 ],
1033 );
1034
1035 settings.delete_user_defined_room_rules(&room_id_a).await.unwrap();
1037
1038 let updated_rules = settings.rules.read().await;
1040 assert_eq!(updated_rules.get_custom_rules_for_room(&room_id_b).len(), 2);
1041 assert!(updated_rules.get_custom_rules_for_room(&room_id_a).is_empty());
1042 }
1043
1044 #[async_test]
1045 async fn test_unmute_room_not_muted() {
1046 let server = MockServer::start().await;
1047 let client = logged_in_client(Some(server.uri())).await;
1048 let room_id = get_test_room_id();
1049
1050 let settings = from_insert_rules(&client, vec![(RuleKind::Room, &room_id, false)]);
1052 assert_eq!(
1053 settings.get_user_defined_room_notification_mode(&room_id).await.unwrap(),
1054 RoomNotificationMode::MentionsAndKeywordsOnly
1055 );
1056
1057 settings.unmute_room(&room_id, IsEncrypted::Yes, IsOneToOne::Yes).await.unwrap();
1059
1060 assert_eq!(
1062 settings.get_user_defined_room_notification_mode(&room_id).await.unwrap(),
1063 RoomNotificationMode::MentionsAndKeywordsOnly
1064 );
1065
1066 let room_rules = get_custom_rules_for_room(&settings, &room_id).await;
1067 assert_eq!(room_rules.len(), 1);
1068 assert_matches!(settings.rules.read().await.ruleset.get(RuleKind::Room, &room_id),
1069 Some(AnyPushRuleRef::Room(rule)) => {
1070 assert_eq!(rule.rule_id, room_id);
1071 assert!(rule.actions.is_empty());
1072 }
1073 );
1074 }
1075
1076 #[async_test]
1077 async fn test_unmute_room() {
1078 let server = MockServer::start().await;
1079 Mock::given(method("PUT")).respond_with(ResponseTemplate::new(200)).mount(&server).await;
1080 Mock::given(method("DELETE")).respond_with(ResponseTemplate::new(200)).mount(&server).await;
1081 let client = logged_in_client(Some(server.uri())).await;
1082 let room_id = get_test_room_id();
1083
1084 let settings = from_insert_rules(&client, vec![(RuleKind::Override, &room_id, false)]);
1086 assert_eq!(
1087 settings.get_user_defined_room_notification_mode(&room_id).await,
1088 Some(RoomNotificationMode::Mute)
1089 );
1090
1091 settings.unmute_room(&room_id, IsEncrypted::No, IsOneToOne::Yes).await.unwrap();
1093
1094 assert!(settings.get_user_defined_room_notification_mode(&room_id).await.is_none());
1096 }
1097
1098 #[async_test]
1099 async fn test_unmute_room_default_mode() {
1100 let server = MockServer::start().await;
1101 Mock::given(method("PUT")).respond_with(ResponseTemplate::new(200)).mount(&server).await;
1102 let client = logged_in_client(Some(server.uri())).await;
1103 let room_id = get_test_room_id();
1104 let settings = client.notification_settings().await;
1105
1106 settings.unmute_room(&room_id, IsEncrypted::No, IsOneToOne::Yes).await.unwrap();
1108
1109 assert_eq!(
1111 Some(RoomNotificationMode::AllMessages),
1112 settings.get_user_defined_room_notification_mode(&room_id).await
1113 );
1114
1115 let room_rules = get_custom_rules_for_room(&settings, &room_id).await;
1116 assert_eq!(room_rules.len(), 1);
1117 assert_matches!(settings.rules.read().await.ruleset.get(RuleKind::Room, &room_id),
1118 Some(AnyPushRuleRef::Room(rule)) => {
1119 assert_eq!(rule.rule_id, room_id);
1120 assert!(!rule.actions.is_empty());
1121 }
1122 );
1123 }
1124
1125 #[async_test]
1126 async fn test_set_default_room_notification_mode() {
1127 let server = MockServer::start().await;
1128 Mock::given(method("PUT")).respond_with(ResponseTemplate::new(200)).mount(&server).await;
1129 let client = logged_in_client(Some(server.uri())).await;
1130
1131 let mut ruleset = get_server_default_ruleset();
1133 ruleset
1134 .set_actions(
1135 RuleKind::Underride,
1136 PredefinedUnderrideRuleId::Message,
1137 vec![Action::Notify],
1138 )
1139 .unwrap();
1140
1141 ruleset
1142 .set_actions(
1143 RuleKind::Underride,
1144 PredefinedUnderrideRuleId::PollStart,
1145 vec![Action::Notify],
1146 )
1147 .unwrap();
1148
1149 let settings = NotificationSettings::new(client, ruleset);
1150 assert_eq!(
1151 settings.get_default_room_notification_mode(IsEncrypted::No, IsOneToOne::No).await,
1152 RoomNotificationMode::AllMessages
1153 );
1154
1155 settings
1157 .set_default_room_notification_mode(
1158 IsEncrypted::No,
1159 IsOneToOne::No,
1160 RoomNotificationMode::MentionsAndKeywordsOnly,
1161 )
1162 .await
1163 .unwrap();
1164
1165 assert_matches!(settings.rules.read().await.ruleset.get(RuleKind::Underride, PredefinedUnderrideRuleId::Message),
1167 Some(AnyPushRuleRef::Underride(rule)) => {
1168 assert!(rule.actions.is_empty());
1169 }
1170 );
1171
1172 assert_matches!(settings.rules.read().await.ruleset.get(RuleKind::Underride, PredefinedUnderrideRuleId::PollStart),
1173 Some(AnyPushRuleRef::Underride(rule)) => {
1174 assert!(rule.actions.is_empty());
1175 }
1176 );
1177
1178 assert_matches!(
1181 settings.get_default_room_notification_mode(IsEncrypted::No, IsOneToOne::No).await,
1182 RoomNotificationMode::MentionsAndKeywordsOnly
1183 );
1184 }
1185
1186 #[async_test]
1187 async fn test_set_default_room_notification_mode_one_to_one() {
1188 let server = MockServer::start().await;
1189 Mock::given(method("PUT")).respond_with(ResponseTemplate::new(200)).mount(&server).await;
1190 let client = logged_in_client(Some(server.uri())).await;
1191
1192 let mut ruleset = get_server_default_ruleset();
1194 ruleset
1195 .set_actions(
1196 RuleKind::Underride,
1197 PredefinedUnderrideRuleId::RoomOneToOne,
1198 vec![Action::Notify],
1199 )
1200 .unwrap();
1201
1202 ruleset
1203 .set_actions(
1204 RuleKind::Underride,
1205 PredefinedUnderrideRuleId::PollStartOneToOne,
1206 vec![Action::Notify],
1207 )
1208 .unwrap();
1209
1210 let settings = NotificationSettings::new(client, ruleset);
1211 assert_eq!(
1212 settings.get_default_room_notification_mode(IsEncrypted::No, IsOneToOne::Yes).await,
1213 RoomNotificationMode::AllMessages
1214 );
1215
1216 settings
1218 .set_default_room_notification_mode(
1219 IsEncrypted::No,
1220 IsOneToOne::Yes,
1221 RoomNotificationMode::MentionsAndKeywordsOnly,
1222 )
1223 .await
1224 .unwrap();
1225
1226 assert_matches!(settings.rules.read().await.ruleset.get(RuleKind::Underride, PredefinedUnderrideRuleId::RoomOneToOne),
1228 Some(AnyPushRuleRef::Underride(rule)) => {
1229 assert!(rule.actions.is_empty());
1230 }
1231 );
1232
1233 assert_matches!(settings.rules.read().await.ruleset.get(RuleKind::Underride, PredefinedUnderrideRuleId::PollStartOneToOne),
1234 Some(AnyPushRuleRef::Underride(rule)) => {
1235 assert!(rule.actions.is_empty());
1236 }
1237 );
1238
1239 assert_matches!(
1242 settings.get_default_room_notification_mode(IsEncrypted::No, IsOneToOne::Yes).await,
1243 RoomNotificationMode::MentionsAndKeywordsOnly
1244 );
1245 }
1246
1247 #[async_test]
1248 async fn test_set_default_room_notification_mode_enables_rules() {
1249 let server = MockServer::start().await;
1250 Mock::given(method("PUT")).respond_with(ResponseTemplate::new(200)).mount(&server).await;
1251 let client = logged_in_client(Some(server.uri())).await;
1252
1253 let mut ruleset = get_server_default_ruleset();
1255 ruleset
1256 .set_actions(RuleKind::Underride, PredefinedUnderrideRuleId::RoomOneToOne, vec![])
1257 .unwrap();
1258
1259 ruleset
1260 .set_actions(RuleKind::Underride, PredefinedUnderrideRuleId::PollStartOneToOne, vec![])
1261 .unwrap();
1262
1263 ruleset
1265 .set_enabled(RuleKind::Underride, PredefinedUnderrideRuleId::RoomOneToOne, false)
1266 .unwrap();
1267
1268 let settings = NotificationSettings::new(client, ruleset);
1269
1270 settings
1272 .set_default_room_notification_mode(
1273 IsEncrypted::No,
1274 IsOneToOne::Yes,
1275 RoomNotificationMode::AllMessages,
1276 )
1277 .await
1278 .unwrap();
1279
1280 assert_matches!(
1283 settings.get_default_room_notification_mode(IsEncrypted::No, IsOneToOne::Yes).await,
1284 RoomNotificationMode::AllMessages
1285 );
1286 }
1287
1288 #[async_test]
1289 async fn test_list_keywords() {
1290 let server = MockServer::start().await;
1291 let client = logged_in_client(Some(server.uri())).await;
1292
1293 let ruleset = get_server_default_ruleset();
1295 let settings = NotificationSettings::new(client.clone(), ruleset);
1296
1297 let keywords = settings.enabled_keywords().await;
1298
1299 assert!(keywords.is_empty());
1300
1301 let mut ruleset = get_server_default_ruleset();
1303 ruleset
1304 .insert(
1305 NewPushRule::Content(NewPatternedPushRule::new(
1306 "a".to_owned(),
1307 "a".to_owned(),
1308 vec![],
1309 )),
1310 None,
1311 None,
1312 )
1313 .unwrap();
1314 ruleset
1316 .insert(
1317 NewPushRule::Content(NewPatternedPushRule::new(
1318 "a_bis".to_owned(),
1319 "a".to_owned(),
1320 vec![],
1321 )),
1322 None,
1323 None,
1324 )
1325 .unwrap();
1326 ruleset
1327 .insert(
1328 NewPushRule::Content(NewPatternedPushRule::new(
1329 "b".to_owned(),
1330 "b".to_owned(),
1331 vec![],
1332 )),
1333 None,
1334 None,
1335 )
1336 .unwrap();
1337
1338 let settings = NotificationSettings::new(client, ruleset);
1339
1340 let keywords = settings.enabled_keywords().await;
1341 assert_eq!(keywords.len(), 2);
1342 assert!(keywords.get("a").is_some());
1343 assert!(keywords.get("b").is_some())
1344 }
1345
1346 #[async_test]
1347 async fn test_add_keyword_missing() {
1348 let server = MockServer::start().await;
1349 let client = logged_in_client(Some(server.uri())).await;
1350 let settings = client.notification_settings().await;
1351
1352 Mock::given(method("PUT"))
1353 .and(path("/_matrix/client/r0/pushrules/global/content/banana"))
1354 .respond_with(ResponseTemplate::new(200))
1355 .expect(1)
1356 .mount(&server)
1357 .await;
1358
1359 settings.add_keyword("banana".to_owned()).await.unwrap();
1360
1361 let keywords = settings.enabled_keywords().await;
1363 assert_eq!(keywords.len(), 1);
1364 assert!(keywords.get("banana").is_some());
1365
1366 let rule_enabled =
1368 settings.is_push_rule_enabled(RuleKind::Content, "banana").await.unwrap();
1369 assert!(rule_enabled)
1370 }
1371
1372 #[async_test]
1373 async fn test_add_keyword_disabled() {
1374 let server = MockServer::start().await;
1375 let client = logged_in_client(Some(server.uri())).await;
1376
1377 let mut ruleset = get_server_default_ruleset();
1378 ruleset
1379 .insert(
1380 NewPushRule::Content(NewPatternedPushRule::new(
1381 "banana_two".to_owned(),
1382 "banana".to_owned(),
1383 vec![],
1384 )),
1385 None,
1386 None,
1387 )
1388 .unwrap();
1389 ruleset.set_enabled(RuleKind::Content, "banana_two", false).unwrap();
1390 ruleset
1391 .insert(
1392 NewPushRule::Content(NewPatternedPushRule::new(
1393 "banana_one".to_owned(),
1394 "banana".to_owned(),
1395 vec![],
1396 )),
1397 None,
1398 None,
1399 )
1400 .unwrap();
1401 ruleset.set_enabled(RuleKind::Content, "banana_one", false).unwrap();
1402
1403 let settings = NotificationSettings::new(client, ruleset);
1404 Mock::given(method("PUT"))
1405 .and(path("/_matrix/client/r0/pushrules/global/content/banana_one/enabled"))
1406 .respond_with(ResponseTemplate::new(200))
1407 .expect(1)
1408 .mount(&server)
1409 .await;
1410
1411 settings.add_keyword("banana".to_owned()).await.unwrap();
1412
1413 let keywords = settings.enabled_keywords().await;
1415
1416 assert_eq!(keywords.len(), 1);
1417 assert!(keywords.get("banana").is_some());
1418
1419 let first_rule_enabled =
1421 settings.is_push_rule_enabled(RuleKind::Content, "banana_one").await.unwrap();
1422 assert!(first_rule_enabled);
1423 let second_rule_enabled =
1424 settings.is_push_rule_enabled(RuleKind::Content, "banana_two").await.unwrap();
1425 assert!(!second_rule_enabled);
1426 }
1427
1428 #[async_test]
1429 async fn test_add_keyword_noop() {
1430 let server = MockServer::start().await;
1431 let client = logged_in_client(Some(server.uri())).await;
1432
1433 let mut ruleset = get_server_default_ruleset();
1434 ruleset
1435 .insert(
1436 NewPushRule::Content(NewPatternedPushRule::new(
1437 "banana_two".to_owned(),
1438 "banana".to_owned(),
1439 vec![],
1440 )),
1441 None,
1442 None,
1443 )
1444 .unwrap();
1445 ruleset
1446 .insert(
1447 NewPushRule::Content(NewPatternedPushRule::new(
1448 "banana_one".to_owned(),
1449 "banana".to_owned(),
1450 vec![],
1451 )),
1452 None,
1453 None,
1454 )
1455 .unwrap();
1456 ruleset.set_enabled(RuleKind::Content, "banana_one", false).unwrap();
1457
1458 let settings = NotificationSettings::new(client, ruleset);
1459 settings.add_keyword("banana".to_owned()).await.unwrap();
1460
1461 let keywords = settings.enabled_keywords().await;
1463
1464 assert_eq!(keywords.len(), 1);
1465 assert!(keywords.get("banana").is_some());
1466
1467 let first_rule_enabled =
1468 settings.is_push_rule_enabled(RuleKind::Content, "banana_one").await.unwrap();
1469 assert!(!first_rule_enabled);
1470 let second_rule_enabled =
1471 settings.is_push_rule_enabled(RuleKind::Content, "banana_two").await.unwrap();
1472 assert!(second_rule_enabled);
1473 }
1474
1475 #[async_test]
1476 async fn test_remove_keyword_all() {
1477 let server = MockServer::start().await;
1478 let client = logged_in_client(Some(server.uri())).await;
1479
1480 let mut ruleset = get_server_default_ruleset();
1481 ruleset
1482 .insert(
1483 NewPushRule::Content(NewPatternedPushRule::new(
1484 "banana_two".to_owned(),
1485 "banana".to_owned(),
1486 vec![],
1487 )),
1488 None,
1489 None,
1490 )
1491 .unwrap();
1492 ruleset
1493 .insert(
1494 NewPushRule::Content(NewPatternedPushRule::new(
1495 "banana_one".to_owned(),
1496 "banana".to_owned(),
1497 vec![],
1498 )),
1499 None,
1500 None,
1501 )
1502 .unwrap();
1503 ruleset.set_enabled(RuleKind::Content, "banana_one", false).unwrap();
1504
1505 let settings = NotificationSettings::new(client, ruleset);
1506
1507 Mock::given(method("DELETE"))
1508 .and(path("/_matrix/client/r0/pushrules/global/content/banana_one"))
1509 .respond_with(ResponseTemplate::new(200))
1510 .expect(1)
1511 .mount(&server)
1512 .await;
1513 Mock::given(method("DELETE"))
1514 .and(path("/_matrix/client/r0/pushrules/global/content/banana_two"))
1515 .respond_with(ResponseTemplate::new(200))
1516 .expect(1)
1517 .mount(&server)
1518 .await;
1519
1520 settings.remove_keyword("banana").await.unwrap();
1521
1522 let keywords = settings.enabled_keywords().await;
1524 assert!(keywords.is_empty());
1525
1526 let first_rule_error =
1528 settings.is_push_rule_enabled(RuleKind::Content, "banana_one").await.unwrap_err();
1529 assert_matches!(first_rule_error, NotificationSettingsError::RuleNotFound(_));
1530 let second_rule_error =
1531 settings.is_push_rule_enabled(RuleKind::Content, "banana_two").await.unwrap_err();
1532 assert_matches!(second_rule_error, NotificationSettingsError::RuleNotFound(_));
1533 }
1534
1535 #[async_test]
1536 async fn test_remove_keyword_noop() {
1537 let server = MockServer::start().await;
1538 let client = logged_in_client(Some(server.uri())).await;
1539 let settings = client.notification_settings().await;
1540
1541 settings.remove_keyword("banana").await.unwrap();
1542 }
1543
1544 #[async_test]
1545 async fn test_set_default_room_notification_mode_missing_poll_start() {
1546 let server = MockServer::start().await;
1547 Mock::given(method("PUT")).respond_with(ResponseTemplate::new(200)).mount(&server).await;
1548 let client = logged_in_client(Some(server.uri())).await;
1549
1550 let mut ruleset = get_server_default_ruleset();
1552 ruleset.underride.swap_remove(PredefinedUnderrideRuleId::PollStart.as_str());
1553
1554 let settings = NotificationSettings::new(client, ruleset);
1555 assert_eq!(
1556 settings.get_default_room_notification_mode(IsEncrypted::No, IsOneToOne::No).await,
1557 RoomNotificationMode::AllMessages
1558 );
1559
1560 settings
1562 .set_default_room_notification_mode(
1563 IsEncrypted::No,
1564 IsOneToOne::No,
1565 RoomNotificationMode::MentionsAndKeywordsOnly,
1566 )
1567 .await
1568 .unwrap();
1569
1570 assert_matches!(
1573 settings.get_default_room_notification_mode(IsEncrypted::No, IsOneToOne::No).await,
1574 RoomNotificationMode::MentionsAndKeywordsOnly
1575 );
1576 }
1577}