Skip to content

Commit 817f32e

Browse files
dragonfly1033poljar
authored andcommitted
test(sdk): added configurable login response builders for mock login endpoint.
1 parent 30eb12e commit 817f32e

File tree

2 files changed

+167
-7
lines changed

2 files changed

+167
-7
lines changed

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

Lines changed: 153 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3253,9 +3253,85 @@ impl<'a> MockEndpoint<'a, LoginEndpoint> {
32533253
self.respond_with(ResponseTemplate::new(200).set_body_json(&*test_json::LOGIN))
32543254
}
32553255

3256-
/// Returns a successful response with a given message.
3257-
pub fn ok_with(self, response: ResponseTemplate) -> MatrixMock<'a> {
3258-
self.respond_with(response)
3256+
/// Returns a given response on POST /login requests
3257+
///
3258+
/// This function
3259+
/// to-device messages sent via the `/sendToDevice` endpoint.
3260+
///
3261+
/// # Arguments
3262+
///
3263+
/// * `response` - The response that the mock server sends on POST /login
3264+
/// requests.
3265+
///
3266+
/// # Returns
3267+
///
3268+
/// Returns a [`MatrixMock`] which can be mounted.
3269+
///
3270+
/// # Examples
3271+
///
3272+
/// ```rust
3273+
/// use matrix_sdk::test_utils::mocks::{
3274+
/// LoginResponseTemplate200, MatrixMockServer,
3275+
/// };
3276+
/// use matrix_sdk_test::async_test;
3277+
/// use ruma::{device_id, time::Duration, user_id};
3278+
///
3279+
/// #[async_test]
3280+
/// async fn test_ok_with() {
3281+
/// let server = MatrixMockServer::new().await;
3282+
/// server
3283+
/// .mock_login()
3284+
/// .ok_with(LoginResponseTemplate200::new(
3285+
/// "qwerty",
3286+
/// device_id!("DEADBEEF"),
3287+
/// user_id!("@cheeky_monkey:matrix.org"),
3288+
/// ))
3289+
/// .mount()
3290+
/// .await;
3291+
///
3292+
/// let client = server.client_builder().unlogged().build().await;
3293+
///
3294+
/// let result = client
3295+
/// .matrix_auth()
3296+
/// .login_username("example", "wordpass")
3297+
/// .send()
3298+
/// .await
3299+
/// .unwrap();
3300+
///
3301+
/// assert!(
3302+
/// result.access_tokesn.unwrap() == "qwerty",
3303+
/// "wrong access token in response"
3304+
/// );
3305+
/// assert!(
3306+
/// result.device_id.unwrap() == "DEADBEEF",
3307+
/// "wrong device id in response"
3308+
/// );
3309+
/// assert!(
3310+
/// result.user_id.unwrap() == "@cheeky_monkey:matrix.org",
3311+
/// "wrong user id in response"
3312+
/// );
3313+
/// }
3314+
/// ```
3315+
pub fn ok_with(self, response: LoginResponseTemplate200) -> MatrixMock<'a> {
3316+
self.respond_with(ResponseTemplate::new(200).set_body_json(json!({
3317+
"access_token": response.access_token,
3318+
"device_id": response.device_id,
3319+
"user_id": response.user_id,
3320+
"expires_in": response.expires_in.map(|duration| { duration.as_millis() }),
3321+
"refresh_token": response.refresh_token,
3322+
"well_known": response.well_known.map(|vals| {
3323+
json!({
3324+
"m.homeserver": {
3325+
"base_url": vals.homeserver_url
3326+
},
3327+
"m.identity_server": vals.identity_url.map(|url| {
3328+
json!({
3329+
"base_url": url
3330+
})
3331+
})
3332+
})
3333+
}),
3334+
})))
32593335
}
32603336

32613337
/// Ensures that the body of the request is a superset of the provided
@@ -3265,6 +3341,80 @@ impl<'a> MockEndpoint<'a, LoginEndpoint> {
32653341
}
32663342
}
32673343

3344+
#[derive(Default)]
3345+
struct LoginResponseWellKnown {
3346+
/// Required if well_known is used: The base URL for the homeserver for
3347+
/// client-server connections.
3348+
homeserver_url: String,
3349+
3350+
/// Required if well_known and m.identity_server are used: The base URL for
3351+
/// the identity server for client-server connections.
3352+
identity_url: Option<String>,
3353+
}
3354+
3355+
/// A response to a [`LoginEndpoint`] query with status code 200.
3356+
#[derive(Default)]
3357+
pub struct LoginResponseTemplate200 {
3358+
/// Required: An access token for the account. This access token can then be
3359+
/// used to authorize other requests.
3360+
access_token: Option<String>,
3361+
3362+
/// Required: ID of the logged-in device. Will be the same as the
3363+
/// corresponding parameter in the request, if one was specified.
3364+
device_id: Option<OwnedDeviceId>,
3365+
3366+
/// The lifetime of the access token, in milliseconds. Once the access token
3367+
/// has expired a new access token can be obtained by using the provided
3368+
/// refresh token. If no refresh token is provided, the client will need
3369+
/// to re-log in to obtain a new access token. If not given, the client
3370+
/// can assume that the access token will not expire.
3371+
expires_in: Option<Duration>,
3372+
3373+
/// A refresh token for the account. This token can be used to obtain a new
3374+
/// access token when it expires by calling the /refresh endpoint.
3375+
refresh_token: Option<String>,
3376+
3377+
/// Required: The fully-qualified Matrix ID for the account.
3378+
user_id: Option<OwnedUserId>,
3379+
3380+
/// Optional client configuration provided by the server.
3381+
well_known: Option<LoginResponseWellKnown>,
3382+
}
3383+
3384+
impl LoginResponseTemplate200 {
3385+
/// Constructor for empty response
3386+
pub fn new<T1: Into<OwnedDeviceId>, T2: Into<OwnedUserId>>(
3387+
access_token: &str,
3388+
device_id: T1,
3389+
user_id: T2,
3390+
) -> Self {
3391+
Self {
3392+
access_token: Some(access_token.to_owned()),
3393+
device_id: Some(device_id.into()),
3394+
user_id: Some(user_id.into()),
3395+
..Default::default()
3396+
}
3397+
}
3398+
3399+
/// sets expires_in
3400+
pub fn expires_in(mut self, value: Duration) -> Self {
3401+
self.expires_in = Some(value);
3402+
self
3403+
}
3404+
3405+
/// sets refresh_token
3406+
pub fn refresh_token(mut self, value: &str) -> Self {
3407+
self.refresh_token = Some(value.to_owned());
3408+
self
3409+
}
3410+
3411+
/// sets well_known which takes a homeserver_url and an optional
3412+
/// identity_url
3413+
pub fn well_known(mut self, homeserver_url: String, identity_url: Option<String>) -> Self {
3414+
self.well_known = Some(LoginResponseWellKnown { homeserver_url, identity_url });
3415+
self
3416+
}
3417+
}
32683418

32693419
/// A prebuilt mock for `GET /devices` requests.
32703420
pub struct DevicesEndpoint;

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ use matrix_sdk::{
1111
executor::spawn,
1212
store::RoomLoadSettings,
1313
test_utils::{
14-
client::mock_session_meta, logged_in_client_with_server, mocks::MatrixMockServer,
14+
client::mock_session_meta,
15+
logged_in_client_with_server,
16+
mocks::{LoginResponseTemplate200, MatrixMockServer},
1517
no_retry_test_client_with_server, test_client_builder_with_server,
1618
},
1719
HttpError, RefreshTokenError, SessionChange, SessionTokens,
@@ -22,7 +24,7 @@ use ruma::{
2224
client::{account::register, error::ErrorKind},
2325
MatrixVersion,
2426
},
25-
assign,
27+
assign, owned_device_id, owned_user_id,
2628
};
2729
use serde_json::json;
2830
use tokio::sync::{broadcast::error::TryRecvError, mpsc};
@@ -47,7 +49,15 @@ async fn test_login_username_refresh_token() {
4749
server
4850
.mock_login()
4951
.body_matches_partial_json(json!({"refresh_token": true}))
50-
.ok_with(ResponseTemplate::new(200).set_body_json(&*test_json::LOGIN_WITH_REFRESH_TOKEN))
52+
.ok_with(
53+
LoginResponseTemplate200::new(
54+
"abc123",
55+
owned_device_id!("GHTYAJCE"),
56+
owned_user_id!("@cheeky_monkey:matrix.org"),
57+
)
58+
.expires_in(Duration::from_millis(432000000))
59+
.refresh_token("zyx987"),
60+
)
5161
.mount()
5262
.await;
5363

@@ -60,7 +70,7 @@ async fn test_login_username_refresh_token() {
6070
.send()
6171
.await
6272
.unwrap();
63-
73+
6474
assert!(client.is_active(), "Client should be active");
6575
res.refresh_token.unwrap();
6676
}

0 commit comments

Comments
 (0)