From 736f2c05109711aba8a3f3ac0917859d09bead0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 11 Dec 2024 12:30:30 +0100 Subject: [PATCH] feat(room): add `Room::update_room_visibility` function --- bindings/matrix-sdk-ffi/src/room.rs | 10 +++- .../matrix-sdk/src/room/privacy_settings.rs | 26 +++++++++- crates/matrix-sdk/src/test_utils/mocks.rs | 48 +++++++++++++++++++ 3 files changed, 82 insertions(+), 2 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/room.rs b/bindings/matrix-sdk-ffi/src/room.rs index a1b0d2f6d91..065f1c6e54e 100644 --- a/bindings/matrix-sdk-ffi/src/room.rs +++ b/bindings/matrix-sdk-ffi/src/room.rs @@ -34,7 +34,7 @@ use tracing::error; use super::RUNTIME; use crate::{ chunk_iterator::ChunkIterator, - client::JoinRule, + client::{JoinRule, RoomVisibility}, error::{ClientError, MediaInfoError, NotYetImplemented, RoomError}, event::{MessageLikeEventType, RoomMessageEventMessageType, StateEventType}, identity_status_change::IdentityStatusChange, @@ -944,6 +944,14 @@ impl Room { let new_rule: RumaJoinRule = new_rule.try_into()?; self.inner.update_join_rule(new_rule).await.map_err(Into::into) } + + /// Update the room's visibility in the room directory. + pub async fn update_room_visibility( + &self, + visibility: RoomVisibility, + ) -> Result<(), ClientError> { + self.inner.update_room_visibility(visibility.into()).await.map_err(Into::into) + } } /// Generates a `matrix.to` permalink to the given room alias. diff --git a/crates/matrix-sdk/src/room/privacy_settings.rs b/crates/matrix-sdk/src/room/privacy_settings.rs index 321274d6e84..10e33bbe68e 100644 --- a/crates/matrix-sdk/src/room/privacy_settings.rs +++ b/crates/matrix-sdk/src/room/privacy_settings.rs @@ -1,5 +1,5 @@ use ruma::{ - api::client::state::send_state_event, + api::client::{directory::set_room_visibility, room::Visibility, state::send_state_event}, assign, events::{ room::{ @@ -89,12 +89,22 @@ impl Room { self.client.remove_room_alias(&previous_alias).await?; Ok(()) } + + /// Update the visibility for this room in the room directory. + pub async fn update_room_visibility(&self, visibility: Visibility) -> Result<()> { + let request = set_room_visibility::v3::Request::new(self.room_id().to_owned(), visibility); + + self.client.send(request, None).await?; + + Ok(()) + } } #[cfg(all(test, not(target_arch = "wasm32")))] mod tests { use matrix_sdk_test::{async_test, JoinedRoomBuilder, StateTestEvent}; use ruma::{ + api::client::room::Visibility, event_id, events::{ room::{history_visibility::HistoryVisibility, join_rules::JoinRule}, @@ -413,4 +423,18 @@ mod tests { let ret = room.update_join_rule(JoinRule::Public).await; assert!(ret.is_ok()); } + + #[async_test] + async fn test_update_room_visibility() { + let server = MatrixMockServer::new().await; + let client = server.client_builder().build().await; + + let room_id = room_id!("!a:b.c"); + let room = server.sync_joined_room(&client, room_id).await; + + server.mock_room_directory_set_room_visibility().ok().mock_once().mount().await; + + let ret = room.update_room_visibility(Visibility::Private).await; + assert!(ret.is_ok()); + } } diff --git a/crates/matrix-sdk/src/test_utils/mocks.rs b/crates/matrix-sdk/src/test_utils/mocks.rs index edf85171669..3bc334568ee 100644 --- a/crates/matrix-sdk/src/test_utils/mocks.rs +++ b/crates/matrix-sdk/src/test_utils/mocks.rs @@ -656,6 +656,43 @@ impl MatrixMockServer { MockEndpoint { mock, server: &self.server, endpoint: PublicRoomsEndpoint } } + /// Create a prebuilt mock for setting a room's visibility in the room + /// directory. + /// + /// # Examples + /// + /// ``` + /// # tokio_test::block_on(async { + /// use matrix_sdk::{ruma::room_id, test_utils::mocks::MatrixMockServer}; + /// use ruma::api::client::room::Visibility; + /// + /// let mock_server = MatrixMockServer::new().await; + /// let client = mock_server.client_builder().build().await; + /// + /// mock_server + /// .mock_room_directory_set_room_visibility() + /// .ok() + /// .mock_once() + /// .mount() + /// .await; + /// + /// let room = mock_server + /// .sync_joined_room(&client, room_id!("!room_id:localhost")) + /// .await; + /// + /// room.update_room_visibility(Visibility::Private) + /// .await + /// .expect("We should be able to update the room's visibility"); + /// # anyhow::Ok(()) }); + /// ``` + pub fn mock_room_directory_set_room_visibility( + &self, + ) -> MockEndpoint<'_, SetRoomVisibilityEndpoint> { + let mock = Mock::given(method("PUT")) + .and(path_regex(r"^/_matrix/client/v3/directory/list/room/.*$")); + MockEndpoint { mock, server: &self.server, endpoint: SetRoomVisibilityEndpoint } + } + /// Create a prebuilt mock for fetching information about key storage /// backups. /// @@ -1795,6 +1832,17 @@ impl<'a> MockEndpoint<'a, PublicRoomsEndpoint> { } } +/// A prebuilt mock for setting the room's visibility in the room directory. +pub struct SetRoomVisibilityEndpoint; + +impl<'a> MockEndpoint<'a, SetRoomVisibilityEndpoint> { + /// Returns an endpoint that updates the room's visibility. + pub fn ok(self) -> MatrixMock<'a> { + let mock = self.mock.respond_with(ResponseTemplate::new(200).set_body_json(json!({}))); + MatrixMock { server: self.server, mock } + } +} + /// A prebuilt mock for `GET room_keys/version`: storage ("backup") of room /// keys. pub struct RoomKeysVersionEndpoint;