Skip to content

Commit dcd8aa1

Browse files
authored
fix: NotificationSettings::unmute_room didn't clear the cached notification mode
1 parent a4e68ba commit dcd8aa1

File tree

3 files changed

+103
-1
lines changed

3 files changed

+103
-1
lines changed

crates/matrix-sdk-base/src/room/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,19 @@ impl Room {
429429
self.info.read().cached_user_defined_notification_mode
430430
}
431431

432+
/// Removes any existing cached value for the user defined notification
433+
/// mode.
434+
pub fn clear_user_defined_notification_mode(&self) {
435+
self.info.update_if(|info| {
436+
if info.cached_user_defined_notification_mode.is_some() {
437+
info.cached_user_defined_notification_mode = None;
438+
true
439+
} else {
440+
false
441+
}
442+
})
443+
}
444+
432445
/// Get the list of users ids that are considered to be joined members of
433446
/// this room.
434447
pub async fn joined_user_ids(&self) -> StoreResult<Vec<OwnedUserId>> {

crates/matrix-sdk/src/sliding_sync/client.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,8 @@ async fn update_in_memory_caches(
277277
for room in client.joined_rooms() {
278278
if let Some(mode) = rules.get_user_defined_room_notification_mode(room.room_id()) {
279279
room.update_cached_user_defined_notification_mode(mode);
280+
} else {
281+
room.clear_user_defined_notification_mode();
280282
}
281283
}
282284
} else {

crates/matrix-sdk/tests/integration/room/notification_mode.rs

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
use std::time::Duration;
22

33
use assert_matches::assert_matches;
4-
use matrix_sdk::{config::SyncSettings, notification_settings::RoomNotificationMode};
4+
use matrix_sdk::{
5+
SlidingSyncList, config::SyncSettings, notification_settings::RoomNotificationMode,
6+
test_utils::mocks::MatrixMockServer,
7+
};
58
use matrix_sdk_base::RoomState;
69
use matrix_sdk_test::{
710
DEFAULT_TEST_ROOM_ID, InvitedRoomBuilder, JoinedRoomBuilder, SyncResponseBuilder, async_test,
811
event_factory::EventFactory,
912
};
1013
use ruma::{
14+
api::client::sync::sync_events::v5,
15+
events::AnyGlobalAccountDataEvent,
1116
push::{Action, ConditionalPushRule, NewSimplePushRule, Ruleset, Tweak},
1217
room_id,
18+
serde::Raw,
1319
};
1420
use serde_json::json;
1521
use wiremock::{
@@ -102,3 +108,84 @@ async fn test_get_notification_mode() {
102108
let mode = room.notification_mode().await;
103109
assert_eq!(mode, None);
104110
}
111+
112+
#[async_test]
113+
async fn test_cached_notification_mode_is_updated_when_syncing() {
114+
let server = MatrixMockServer::new().await;
115+
let client = server.client_builder().build().await;
116+
117+
// If we receive a sliding sync response with custom rules for a room
118+
let mut ruleset = Ruleset::default();
119+
ruleset.override_ =
120+
[ConditionalPushRule::master(), ConditionalPushRule::suppress_notices()].into();
121+
ruleset.room.insert(
122+
NewSimplePushRule::new(
123+
(*DEFAULT_TEST_ROOM_ID).into(),
124+
vec![Action::Notify, Action::SetTweak(Tweak::Sound("default".into()))],
125+
)
126+
.into(),
127+
);
128+
ruleset.underride = [
129+
ConditionalPushRule::call(),
130+
ConditionalPushRule::room_one_to_one(),
131+
ConditionalPushRule::invite_for_me(client.user_id().unwrap()),
132+
ConditionalPushRule::member_event(),
133+
ConditionalPushRule::message(),
134+
]
135+
.into();
136+
let f = EventFactory::new();
137+
let push_rules: Raw<AnyGlobalAccountDataEvent> = f.push_rules(ruleset).into_raw();
138+
let mut response = v5::Response::new("pos".to_owned());
139+
response.extensions.account_data.global.push(push_rules);
140+
response.rooms.insert(DEFAULT_TEST_ROOM_ID.to_owned(), v5::response::Room::default());
141+
142+
server
143+
.mock_sliding_sync()
144+
.ok_and_run(
145+
&client,
146+
|builder| builder.add_list(SlidingSyncList::builder("rooms")),
147+
response,
148+
)
149+
.await;
150+
151+
server.verify_and_reset().await;
152+
153+
// We can later check the custom mode is applied
154+
let room = client.get_room(&DEFAULT_TEST_ROOM_ID).expect("Room not found");
155+
assert_eq!(
156+
room.cached_user_defined_notification_mode(),
157+
Some(RoomNotificationMode::AllMessages)
158+
);
159+
160+
// Now if we receive a response with no custom push rules for the room, just the
161+
// base ones
162+
let mut ruleset = Ruleset::default();
163+
ruleset.underride = [
164+
ConditionalPushRule::call(),
165+
ConditionalPushRule::room_one_to_one(),
166+
ConditionalPushRule::invite_for_me(client.user_id().unwrap()),
167+
ConditionalPushRule::member_event(),
168+
ConditionalPushRule::message(),
169+
]
170+
.into();
171+
172+
let f = EventFactory::new();
173+
let push_rules: Raw<AnyGlobalAccountDataEvent> = f.push_rules(ruleset).into_raw();
174+
let mut response = v5::Response::new("pos".to_owned());
175+
response.extensions.account_data.global.push(push_rules);
176+
177+
server
178+
.mock_sliding_sync()
179+
.ok_and_run(
180+
&client,
181+
|builder| builder.add_list(SlidingSyncList::builder("rooms")),
182+
response,
183+
)
184+
.await;
185+
186+
server.verify_and_reset().await;
187+
188+
// And the custom notification mode for the room has been removed
189+
let room = client.get_room(&DEFAULT_TEST_ROOM_ID).expect("Room not found");
190+
assert!(room.cached_user_defined_notification_mode().is_none());
191+
}

0 commit comments

Comments
 (0)