Skip to content

Commit ca09298

Browse files
zecakehpoljar
authored andcommitted
feat(sdk): Add support for setting custom profile fields
Signed-off-by: Kévin Commaille <[email protected]>
1 parent c9d3088 commit ca09298

File tree

3 files changed

+87
-4
lines changed

3 files changed

+87
-4
lines changed

crates/matrix-sdk/src/account.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ use ruma::{
4141
error::ErrorKind,
4242
profile::{
4343
AvatarUrl, DisplayName, ProfileFieldName, ProfileFieldValue, StaticProfileField,
44-
get_profile, get_profile_field, set_avatar_url, set_display_name,
44+
get_profile, get_profile_field, set_avatar_url, set_display_name, set_profile_field,
4545
},
4646
uiaa::AuthData,
4747
},
@@ -396,6 +396,26 @@ impl Account {
396396
Ok(response.value)
397397
}
398398

399+
/// Set the given field of our own user's profile.
400+
///
401+
/// [`Client::get_capabilities()`] should be called first to check it the
402+
/// field can be set on the homeserver.
403+
///
404+
/// # Arguments
405+
///
406+
/// * `value` - The value of the profile field to set.
407+
///
408+
/// # Returns
409+
///
410+
/// Returns an error if the request fails.
411+
pub async fn set_profile_field(&self, value: ProfileFieldValue) -> Result<()> {
412+
let user_id = self.client.user_id().ok_or(Error::AuthenticationRequired)?;
413+
let request = set_profile_field::v3::Request::new(user_id.to_owned(), value);
414+
self.client.send(request).await?;
415+
416+
Ok(())
417+
}
418+
399419
/// Change the password of the account.
400420
///
401421
/// # Arguments

crates/matrix-sdk/src/test_utils/mocks/mod.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,6 +1634,17 @@ impl MatrixMockServer {
16341634
.and(path(format!("/_matrix/client/v3/profile/{user_id}/{field}")));
16351635
self.mock_endpoint(mock, GetProfileFieldEndpoint { field })
16361636
}
1637+
1638+
/// Create a prebuilt mock for the endpoint used to set a profile field.
1639+
pub fn mock_set_profile_field(
1640+
&self,
1641+
user_id: &UserId,
1642+
field: ProfileFieldName,
1643+
) -> MockEndpoint<'_, SetProfileFieldEndpoint> {
1644+
let mock = Mock::given(method("PUT"))
1645+
.and(path(format!("/_matrix/client/v3/profile/{user_id}/{field}")));
1646+
self.mock_endpoint(mock, SetProfileFieldEndpoint).expect_default_access_token()
1647+
}
16371648
}
16381649

16391650
/// A specification for a push rule ID.
@@ -4689,3 +4700,13 @@ impl<'a> MockEndpoint<'a, GetProfileFieldEndpoint> {
46894700
}
46904701
}
46914702
}
4703+
4704+
/// A prebuilt mock for `PUT /_matrix/client/*/profile/{user_id}/{key_name}`.
4705+
pub struct SetProfileFieldEndpoint;
4706+
4707+
impl<'a> MockEndpoint<'a, SetProfileFieldEndpoint> {
4708+
/// Returns a successful empty response.
4709+
pub fn ok(self) -> MatrixMock<'a> {
4710+
self.ok_empty_json()
4711+
}
4712+
}

crates/matrix-sdk/tests/integration/account.rs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
use assert_matches2::assert_matches;
22
use matrix_sdk::test_utils::mocks::MatrixMockServer;
33
use matrix_sdk_test::async_test;
4-
use ruma::api::{
5-
MatrixVersion,
6-
client::profile::{ProfileFieldName, ProfileFieldValue, TimeZone},
4+
use ruma::{
5+
api::{
6+
MatrixVersion,
7+
client::profile::{ProfileFieldName, ProfileFieldValue, TimeZone},
8+
},
9+
mxc_uri,
710
};
811
use serde_json::json;
912
use wiremock::{
@@ -111,3 +114,42 @@ async fn test_fetch_profile_field() {
111114
account.fetch_profile_field_of_static::<TimeZone>(user_id.to_owned()).await.unwrap();
112115
assert_eq!(res_tz.as_deref(), Some(tz));
113116
}
117+
118+
#[async_test]
119+
async fn test_set_profile_field() {
120+
let tz = "Africa/Bujumbura";
121+
let display_name = "Alice";
122+
let avatar_url = mxc_uri!("mxc://localhost/1mA63");
123+
124+
let server = MatrixMockServer::new().await;
125+
let client = server.client_builder().server_versions(vec![MatrixVersion::V1_16]).build().await;
126+
let user_id = client.user_id().unwrap();
127+
128+
server
129+
.mock_set_profile_field(user_id, ProfileFieldName::TimeZone)
130+
.ok()
131+
.mock_once()
132+
.named("set m.tz profile field")
133+
.mount()
134+
.await;
135+
server
136+
.mock_set_profile_field(user_id, ProfileFieldName::DisplayName)
137+
.ok()
138+
.mock_once()
139+
.named("set displayname profile field")
140+
.mount()
141+
.await;
142+
server
143+
.mock_set_profile_field(user_id, ProfileFieldName::AvatarUrl)
144+
.ok()
145+
.mock_once()
146+
.named("set avatar_url profile field")
147+
.mount()
148+
.await;
149+
150+
let account = client.account();
151+
152+
account.set_avatar_url(Some(avatar_url)).await.unwrap();
153+
account.set_display_name(Some(display_name)).await.unwrap();
154+
account.set_profile_field(ProfileFieldValue::TimeZone(tz.to_owned())).await.unwrap();
155+
}

0 commit comments

Comments
 (0)