Skip to content

Commit

Permalink
sdk: Remove room from m.direct account data in Room::forget
Browse files Browse the repository at this point in the history
Signed-off-by: Kévin Commaille <[email protected]>
  • Loading branch information
zecakeh authored and bnjbvr committed Oct 15, 2024
1 parent 6dd2e3b commit 0b57ef4
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 4 deletions.
10 changes: 10 additions & 0 deletions crates/matrix-sdk/src/room/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2653,6 +2653,16 @@ impl Room {

let request = forget_room::v3::Request::new(self.inner.room_id().to_owned());
let _response = self.client.send(request, None).await?;

// If it was a DM, remove the room from the `m.direct` global account data.
if self.inner.direct_targets_length() != 0 {
if let Err(e) = self.set_is_direct(false).await {
// It is not important whether we managed to remove the room, it will not have
// any consequences, so just log the error.
warn!(room_id = ?self.room_id(), "failed to remove room from m.direct account data: {e}");
}
}

self.client.store().remove_room(self.inner.room_id()).await?;

Ok(())
Expand Down
76 changes: 72 additions & 4 deletions crates/matrix-sdk/tests/integration/room/left.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,41 @@
use std::time::Duration;

use assert_matches2::assert_matches;
use matrix_sdk::config::SyncSettings;
use matrix_sdk_base::RoomState;
use matrix_sdk_test::{async_test, test_json, DEFAULT_TEST_ROOM_ID};
use ruma::OwnedRoomOrAliasId;
use matrix_sdk_test::{
async_test, test_json, GlobalAccountDataTestEvent, LeftRoomBuilder, SyncResponseBuilder,
DEFAULT_TEST_ROOM_ID,
};
use ruma::{events::direct::DirectEventContent, user_id, OwnedRoomOrAliasId};
use serde_json::json;
use wiremock::{
matchers::{header, method, path_regex},
matchers::{header, method, path, path_regex},
Mock, ResponseTemplate,
};

use crate::{logged_in_client_with_server, mock_sync};

#[async_test]
async fn test_forget_room() {
async fn test_forget_non_direct_room() {
let (client, server) = logged_in_client_with_server().await;
let user_id = client.user_id().unwrap();

Mock::given(method("POST"))
.and(path_regex(r"^/_matrix/client/r0/rooms/.*/forget$"))
.and(header("authorization", "Bearer 1234"))
.respond_with(ResponseTemplate::new(200).set_body_json(&*test_json::EMPTY))
.named("forget")
.expect(1)
.mount(&server)
.await;

Mock::given(method("PUT"))
.and(path(format!("/_matrix/client/r0/user/{user_id}/account_data/m.direct")))
.and(header("authorization", "Bearer 1234"))
.respond_with(ResponseTemplate::new(200).set_body_json(&*test_json::EMPTY))
.named("set_mdirect")
.expect(0)
.mount(&server)
.await;

Expand All @@ -34,6 +50,58 @@ async fn test_forget_room() {
room.forget().await.unwrap();
}

#[async_test]
async fn test_forget_direct_room() {
let (client, server) = logged_in_client_with_server().await;
let user_id = client.user_id().unwrap();
let invited_user_id = user_id!("@invited:localhost");

// Initialize the direct room.
let mut sync_builder = SyncResponseBuilder::new();
sync_builder.add_left_room(LeftRoomBuilder::default());
sync_builder.add_global_account_data_event(GlobalAccountDataTestEvent::Direct);
mock_sync(&server, sync_builder.build_json_sync_response(), None).await;

let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
let _response = client.sync_once(sync_settings).await.unwrap();

let room = client.get_room(&DEFAULT_TEST_ROOM_ID).unwrap();
assert_eq!(room.state(), RoomState::Left);
assert!(room.is_direct().await.unwrap());
assert!(room.direct_targets().contains(invited_user_id));

let direct_account_data = client
.account()
.account_data::<DirectEventContent>()
.await
.expect("getting m.direct account data failed")
.expect("no m.direct account data")
.deserialize()
.expect("failed to deserialize m.direct account data");
assert_matches!(direct_account_data.get(invited_user_id), Some(invited_user_dms));
assert_eq!(invited_user_dms, &[DEFAULT_TEST_ROOM_ID.to_owned()]);

Mock::given(method("POST"))
.and(path_regex(r"^/_matrix/client/r0/rooms/.*/forget$"))
.and(header("authorization", "Bearer 1234"))
.respond_with(ResponseTemplate::new(200).set_body_json(&*test_json::EMPTY))
.named("forget")
.expect(1)
.mount(&server)
.await;

Mock::given(method("PUT"))
.and(path(format!("/_matrix/client/r0/user/{user_id}/account_data/m.direct")))
.and(header("authorization", "Bearer 1234"))
.respond_with(ResponseTemplate::new(200).set_body_json(&*test_json::EMPTY))
.named("set_mdirect")
.expect(1)
.mount(&server)
.await;

room.forget().await.unwrap();
}

#[async_test]
async fn test_rejoin_room() {
let (client, server) = logged_in_client_with_server().await;
Expand Down

0 comments on commit 0b57ef4

Please sign in to comment.