Skip to content

Commit

Permalink
fix(ffi): match the right status code in `Client::is_room_alias_avail…
Browse files Browse the repository at this point in the history
…able`
  • Loading branch information
jmartinesp committed Nov 8, 2024
1 parent 46232ee commit cd62cc6
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 16 deletions.
21 changes: 8 additions & 13 deletions bindings/matrix-sdk-ffi/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1130,21 +1130,16 @@ impl Client {
Ok(())
}

/// Checks if a room alias is available in the current homeserver.
/// Checks if a room alias is not in use yet.
///
/// Returns:
/// - `Ok(true)` if the room alias is available.
/// - `Ok(false)` if it's not (the resolve alias request returned a `404`
/// status code).
/// - An `Err` otherwise.
pub async fn is_room_alias_available(&self, alias: String) -> Result<bool, ClientError> {
let alias = RoomAliasId::parse(alias)?;
match self.inner.resolve_room_alias(&alias).await {
// The room alias was resolved, so it's already in use.
Ok(_) => Ok(false),
Err(HttpError::Reqwest(error)) => {
match error.status() {
// The room alias wasn't found, so it's available.
Some(StatusCode::NOT_FOUND) => Ok(true),
_ => Err(HttpError::Reqwest(error).into()),
}
}
Err(error) => Err(error.into()),
}
self.inner.is_room_alias_available(&alias).await.map_err(Into::into)
}
}

Expand Down
66 changes: 63 additions & 3 deletions crates/matrix-sdk/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ use ruma::{
get_capabilities::{self, Capabilities},
get_supported_versions,
},
error::ErrorKind,
filter::{create_filter::v3::Request as FilterUploadRequest, FilterDefinition},
knock::knock_room,
membership::{join_room_by_id, join_room_by_id_or_alias},
Expand Down Expand Up @@ -1038,6 +1039,27 @@ impl Client {
self.send(request, None).await
}

/// Checks if a room alias is not in use yet.
///
/// Returns:
/// - `Ok(true)` if the room alias is available.
/// - `Ok(false)` if it's not (the resolve alias request returned a `404`
/// status code).
/// - An `Err` otherwise.
pub async fn is_room_alias_available(&self, alias: &RoomAliasId) -> HttpResult<bool> {
match self.resolve_room_alias(alias).await {
// The room alias was resolved, so it's already in use.
Ok(_) => Ok(false),
Err(error) => {
match error.client_api_error_kind() {
// The room alias wasn't found, so it's available.
Some(ErrorKind::NotFound) => Ok(true),
_ => Err(error),
}
}
}
}

/// Update the homeserver from the login response well-known if needed.
///
/// # Arguments
Expand Down Expand Up @@ -2328,7 +2350,7 @@ pub(crate) mod tests {
api::{client::room::create_room::v3::Request as CreateRoomRequest, MatrixVersion},
assign,
events::ignored_user_list::IgnoredUserListEventContent,
owned_room_id, room_id, RoomId, ServerName, UserId,
owned_room_id, room_alias_id, room_id, RoomId, ServerName, UserId,
};
use serde_json::json;
use tokio::{
Expand All @@ -2346,8 +2368,8 @@ pub(crate) mod tests {
client::WeakClient,
config::{RequestConfig, SyncSettings},
test_utils::{
logged_in_client, no_retry_test_client, set_client_session, test_client_builder,
test_client_builder_with_server,
logged_in_client, mocks::MatrixMockServer, no_retry_test_client, set_client_session,
test_client_builder, test_client_builder_with_server,
},
Error,
};
Expand Down Expand Up @@ -2915,4 +2937,42 @@ pub(crate) mod tests {
.await
.unwrap_err();
}

#[async_test]
async fn test_is_room_alias_available_if_alias_is_not_resolved() {
let server = MatrixMockServer::new().await;
let client = logged_in_client(Some(server.server().uri())).await;

server.mock_room_directory_resolve_alias().not_found().expect(1).mount().await;

let ret = client.is_room_alias_available(room_alias_id!("#some_alias:matrix.org")).await;
assert_matches!(ret, Ok(true));
}

#[async_test]
async fn test_is_room_alias_available_if_alias_is_resolved() {
let server = MatrixMockServer::new().await;
let client = logged_in_client(Some(server.server().uri())).await;

server
.mock_room_directory_resolve_alias()
.ok("!some_room_id:matrix.org", Vec::new())
.expect(1)
.mount()
.await;

let ret = client.is_room_alias_available(room_alias_id!("#some_alias:matrix.org")).await;
assert_matches!(ret, Ok(false));
}

#[async_test]
async fn test_is_room_alias_available_if_error_found() {
let server = MatrixMockServer::new().await;
let client = logged_in_client(Some(server.server().uri())).await;

server.mock_room_directory_resolve_alias().error500().expect(1).mount().await;

let ret = client.is_room_alias_available(room_alias_id!("#some_alias:matrix.org")).await;
assert_matches!(ret, Err(_));
}
}
39 changes: 39 additions & 0 deletions crates/matrix-sdk/src/test_utils/mocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,13 @@ impl MatrixMockServer {
.and(header("authorization", "Bearer 1234"));
MockUpload { mock, server: &self.server }
}

/// Create a prebuilt mock for resolving room aliases.
pub fn mock_room_directory_resolve_alias(&self) -> MockResolveRoomAlias<'_> {
let mock = Mock::given(method("GET"))
.and(path_regex(r"/_matrix/client/r0/directory/room/.*"));
MockResolveRoomAlias { mock, server: &self.server }
}
}

/// Parameter to [`MatrixMockServer::sync_room`].
Expand Down Expand Up @@ -511,3 +518,35 @@ impl<'a> MockUpload<'a> {
MatrixMock { mock: self.mock.respond_with(func), server: self.server }
}
}

/// A prebuilt mock for resolving a room alias.
pub struct MockResolveRoomAlias<'a> {
server: &'a MockServer,
mock: MockBuilder,
}

impl<'a> MockResolveRoomAlias<'a> {
/// Returns a data endpoint with a resolved room alias.
pub fn ok(self, room_id: &str, servers: Vec<String>) -> MatrixMock<'a> {
let mock = self.mock.respond_with(ResponseTemplate::new(200).set_body_json(json!({
"room_id": room_id,
"servers": servers,
})));
MatrixMock { server: self.server, mock }
}

/// Returns a data endpoint for a room alias that does not exit.
pub fn not_found(self) -> MatrixMock<'a> {
let mock = self.mock.respond_with(ResponseTemplate::new(404).set_body_json(json!({
"errcode": "M_NOT_FOUND",
"error": "Room alias not found."
})));
MatrixMock { server: self.server, mock }
}

/// Returns a data endpoint with a server error.
pub fn error500(self) -> MatrixMock<'a> {
let mock = self.mock.respond_with(ResponseTemplate::new(500));
MatrixMock { server: self.server, mock }
}
}

0 comments on commit cd62cc6

Please sign in to comment.