fix: NotificationSettings::unmute_room didn't clear the cached notification mode

This commit is contained in:
Jorge Martin Espinosa
2025-10-17 12:02:38 +02:00
committed by GitHub
parent a4e68ba885
commit dcd8aa13f0
3 changed files with 103 additions and 1 deletions
+13
View File
@@ -429,6 +429,19 @@ impl Room {
self.info.read().cached_user_defined_notification_mode
}
/// Removes any existing cached value for the user defined notification
/// mode.
pub fn clear_user_defined_notification_mode(&self) {
self.info.update_if(|info| {
if info.cached_user_defined_notification_mode.is_some() {
info.cached_user_defined_notification_mode = None;
true
} else {
false
}
})
}
/// Get the list of users ids that are considered to be joined members of
/// this room.
pub async fn joined_user_ids(&self) -> StoreResult<Vec<OwnedUserId>> {
@@ -277,6 +277,8 @@ async fn update_in_memory_caches(
for room in client.joined_rooms() {
if let Some(mode) = rules.get_user_defined_room_notification_mode(room.room_id()) {
room.update_cached_user_defined_notification_mode(mode);
} else {
room.clear_user_defined_notification_mode();
}
}
} else {
@@ -1,15 +1,21 @@
use std::time::Duration;
use assert_matches::assert_matches;
use matrix_sdk::{config::SyncSettings, notification_settings::RoomNotificationMode};
use matrix_sdk::{
SlidingSyncList, config::SyncSettings, notification_settings::RoomNotificationMode,
test_utils::mocks::MatrixMockServer,
};
use matrix_sdk_base::RoomState;
use matrix_sdk_test::{
DEFAULT_TEST_ROOM_ID, InvitedRoomBuilder, JoinedRoomBuilder, SyncResponseBuilder, async_test,
event_factory::EventFactory,
};
use ruma::{
api::client::sync::sync_events::v5,
events::AnyGlobalAccountDataEvent,
push::{Action, ConditionalPushRule, NewSimplePushRule, Ruleset, Tweak},
room_id,
serde::Raw,
};
use serde_json::json;
use wiremock::{
@@ -102,3 +108,84 @@ async fn test_get_notification_mode() {
let mode = room.notification_mode().await;
assert_eq!(mode, None);
}
#[async_test]
async fn test_cached_notification_mode_is_updated_when_syncing() {
let server = MatrixMockServer::new().await;
let client = server.client_builder().build().await;
// If we receive a sliding sync response with custom rules for a room
let mut ruleset = Ruleset::default();
ruleset.override_ =
[ConditionalPushRule::master(), ConditionalPushRule::suppress_notices()].into();
ruleset.room.insert(
NewSimplePushRule::new(
(*DEFAULT_TEST_ROOM_ID).into(),
vec![Action::Notify, Action::SetTweak(Tweak::Sound("default".into()))],
)
.into(),
);
ruleset.underride = [
ConditionalPushRule::call(),
ConditionalPushRule::room_one_to_one(),
ConditionalPushRule::invite_for_me(client.user_id().unwrap()),
ConditionalPushRule::member_event(),
ConditionalPushRule::message(),
]
.into();
let f = EventFactory::new();
let push_rules: Raw<AnyGlobalAccountDataEvent> = f.push_rules(ruleset).into_raw();
let mut response = v5::Response::new("pos".to_owned());
response.extensions.account_data.global.push(push_rules);
response.rooms.insert(DEFAULT_TEST_ROOM_ID.to_owned(), v5::response::Room::default());
server
.mock_sliding_sync()
.ok_and_run(
&client,
|builder| builder.add_list(SlidingSyncList::builder("rooms")),
response,
)
.await;
server.verify_and_reset().await;
// We can later check the custom mode is applied
let room = client.get_room(&DEFAULT_TEST_ROOM_ID).expect("Room not found");
assert_eq!(
room.cached_user_defined_notification_mode(),
Some(RoomNotificationMode::AllMessages)
);
// Now if we receive a response with no custom push rules for the room, just the
// base ones
let mut ruleset = Ruleset::default();
ruleset.underride = [
ConditionalPushRule::call(),
ConditionalPushRule::room_one_to_one(),
ConditionalPushRule::invite_for_me(client.user_id().unwrap()),
ConditionalPushRule::member_event(),
ConditionalPushRule::message(),
]
.into();
let f = EventFactory::new();
let push_rules: Raw<AnyGlobalAccountDataEvent> = f.push_rules(ruleset).into_raw();
let mut response = v5::Response::new("pos".to_owned());
response.extensions.account_data.global.push(push_rules);
server
.mock_sliding_sync()
.ok_and_run(
&client,
|builder| builder.add_list(SlidingSyncList::builder("rooms")),
response,
)
.await;
server.verify_and_reset().await;
// And the custom notification mode for the room has been removed
let room = client.get_room(&DEFAULT_TEST_ROOM_ID).expect("Room not found");
assert!(room.cached_user_defined_notification_mode().is_none());
}