From 6026b0c4b7a611cb03476800121cc9e2e2ba63ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Mon, 24 Feb 2025 15:55:23 +0100 Subject: [PATCH] test(oidc): Use MatrixMockServer for qrcode login tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Commaille --- .../src/authentication/oidc/qrcode/login.rs | 68 ++++++------------ crates/matrix-sdk/src/test_utils/mocks.rs | 72 +++++++++++++++++++ 2 files changed, 92 insertions(+), 48 deletions(-) diff --git a/crates/matrix-sdk/src/authentication/oidc/qrcode/login.rs b/crates/matrix-sdk/src/authentication/oidc/qrcode/login.rs index 59da39b9c..53afd7121 100644 --- a/crates/matrix-sdk/src/authentication/oidc/qrcode/login.rs +++ b/crates/matrix-sdk/src/authentication/oidc/qrcode/login.rs @@ -358,11 +358,11 @@ mod test { requests::GrantType, }; use matrix_sdk_base::crypto::types::{qr_login::QrCodeModeData, SecretsBundle}; - use matrix_sdk_test::{async_test, test_json}; + use matrix_sdk_test::async_test; use serde_json::{json, Value}; use url::Url; use wiremock::{ - matchers::{header, method, path}, + matchers::{method, path}, Mock, MockServer, ResponseTemplate, }; @@ -374,6 +374,7 @@ mod test { }, config::RequestConfig, http_client::HttpClient, + test_utils::mocks::MatrixMockServer, }; enum AliceBehaviour { @@ -521,7 +522,7 @@ mod test { fn token() -> Value { json!({ - "access_token": "mat_z65RpDAbvR5aTr7MzD0aPw40xFbwch_09xTgn", + "access_token": "1234", "expires_in": 300, "refresh_token": "mar_CHFh124AMHsdishuHgLSx1svdKMVQA_080gj2", "scope": "urn:matrix:org.matrix.msc2967.client:api:* \ @@ -636,40 +637,20 @@ mod test { #[async_test] async fn test_qr_login() { - let server = MockServer::start().await; - let rendezvous_server = MockedRendezvousServer::new(&server, "abcdEFG12345").await; + let server = MatrixMockServer::new().await; + let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await; let (sender, receiver) = tokio::sync::oneshot::channel(); - mock_oauth_authorization_server(&server, ResponseTemplate::new(200).set_body_json(token())) - .await; + mock_oauth_authorization_server( + server.server(), + ResponseTemplate::new(200).set_body_json(token()), + ) + .await; - Mock::given(method("GET")) - .and(path("/_matrix/client/r0/account/whoami")) - .respond_with(ResponseTemplate::new(200).set_body_json(&*test_json::WHOAMI)) - .mount(&server) - .await; - - Mock::given(method("GET")) - .and(path("/_matrix/client/versions")) - .respond_with(ResponseTemplate::new(200).set_body_json(&*test_json::VERSIONS)) - .mount(&server) - .await; - - Mock::given(method("POST")) - .and(path("/_matrix/client/r0/keys/upload")) - .and(header("authorization", "Bearer mat_z65RpDAbvR5aTr7MzD0aPw40xFbwch_09xTgn")) - .respond_with(ResponseTemplate::new(200).set_body_json(&*test_json::KEYS_UPLOAD)) - .expect(1) - .mount(&server) - .await; - - Mock::given(method("POST")) - .and(path("/_matrix/client/r0/keys/query")) - .and(header("authorization", "Bearer mat_z65RpDAbvR5aTr7MzD0aPw40xFbwch_09xTgn")) - .respond_with(ResponseTemplate::new(200).set_body_json(json!({}))) - .expect(1) - .mount(&server) - .await; + server.mock_versions().ok().expect(1..).named("versions").mount().await; + server.mock_who_am_i().ok().expect(1).named("whoami").mount().await; + server.mock_upload_keys().ok().expect(1).named("upload_keys").mount().await; + server.mock_query_keys().ok().expect(1).named("query_keys").mount().await; let client = HttpClient::new(reqwest::Client::new(), Default::default()); let alice = SecureChannel::new(client, &rendezvous_server.homeserver_url) @@ -732,23 +713,14 @@ mod test { token_response: ResponseTemplate, alice_behavior: AliceBehaviour, ) -> Result<(), QRCodeLoginError> { - let server = MockServer::start().await; - let rendezvous_server = MockedRendezvousServer::new(&server, "abcdEFG12345").await; + let server = MatrixMockServer::new().await; + let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await; let (sender, receiver) = tokio::sync::oneshot::channel(); - mock_oauth_authorization_server(&server, token_response).await; + mock_oauth_authorization_server(server.server(), token_response).await; - Mock::given(method("GET")) - .and(path("/_matrix/client/r0/account/whoami")) - .respond_with(ResponseTemplate::new(200).set_body_json(&*test_json::WHOAMI)) - .mount(&server) - .await; - - Mock::given(method("GET")) - .and(path("/_matrix/client/versions")) - .respond_with(ResponseTemplate::new(200).set_body_json(&*test_json::VERSIONS)) - .mount(&server) - .await; + server.mock_versions().ok().named("versions").mount().await; + server.mock_who_am_i().ok().named("whoami").mount().await; let client = HttpClient::new(reqwest::Client::new(), Default::default()); let alice = SecureChannel::new(client, &rendezvous_server.homeserver_url) diff --git a/crates/matrix-sdk/src/test_utils/mocks.rs b/crates/matrix-sdk/src/test_utils/mocks.rs index 27386508a..8d6069881 100644 --- a/crates/matrix-sdk/src/test_utils/mocks.rs +++ b/crates/matrix-sdk/src/test_utils/mocks.rs @@ -940,6 +940,33 @@ impl MatrixMockServer { .and(header("authorization", "Bearer 1234")); MockEndpoint { mock, server: &self.server, endpoint: SetRoomPinnedEventsEndpoint } } + + /// Creates a prebuilt mock for the endpoint used to get information about + /// the owner of the current access token. + pub fn mock_who_am_i(&self) -> MockEndpoint<'_, WhoAmIEndpoint> { + let mock = Mock::given(method("GET")) + .and(path_regex(r"^/_matrix/client/v3/account/whoami")) + .and(header("authorization", "Bearer 1234")); + MockEndpoint { mock, server: &self.server, endpoint: WhoAmIEndpoint } + } + + /// Creates a prebuilt mock for the endpoint used to publish end-to-end + /// encryption keys. + pub fn mock_upload_keys(&self) -> MockEndpoint<'_, UploadKeysEndpoint> { + let mock = Mock::given(method("POST")) + .and(path_regex(r"^/_matrix/client/v3/keys/upload")) + .and(header("authorization", "Bearer 1234")); + MockEndpoint { mock, server: &self.server, endpoint: UploadKeysEndpoint } + } + + /// Creates a prebuilt mock for the endpoint used to query end-to-end + /// encryption keys. + pub fn mock_query_keys(&self) -> MockEndpoint<'_, QueryKeysEndpoint> { + let mock = Mock::given(method("POST")) + .and(path_regex(r"^/_matrix/client/v3/keys/query")) + .and(header("authorization", "Bearer 1234")); + MockEndpoint { mock, server: &self.server, endpoint: QueryKeysEndpoint } + } } /// Parameter to [`MatrixMockServer::sync_room`]. @@ -2342,3 +2369,48 @@ impl<'a> MockEndpoint<'a, SetRoomPinnedEventsEndpoint> { MatrixMock { server: self.server, mock } } } + +/// A prebuilt mock for `GET /account/whoami` request. +pub struct WhoAmIEndpoint; + +impl<'a> MockEndpoint<'a, WhoAmIEndpoint> { + /// Returns a successful response with the user ID `@joe:example.org` and no + /// device ID. + pub fn ok(self) -> MatrixMock<'a> { + let mock = self.mock.respond_with(ResponseTemplate::new(200).set_body_json(json!({ + "user_id": "@joe:example.org", + }))); + + MatrixMock { server: self.server, mock } + } +} + +/// A prebuilt mock for `POST /keys/upload` request. +pub struct UploadKeysEndpoint; + +impl<'a> MockEndpoint<'a, UploadKeysEndpoint> { + /// Returns a successful response with counts of 10 curve25519 keys and 20 + /// signed curve25519 keys. + pub fn ok(self) -> MatrixMock<'a> { + let mock = self.mock.respond_with(ResponseTemplate::new(200).set_body_json(json!({ + "one_time_key_counts": { + "curve25519": 10, + "signed_curve25519": 20, + }, + }))); + + MatrixMock { server: self.server, mock } + } +} + +/// A prebuilt mock for `POST /keys/query` request. +pub struct QueryKeysEndpoint; + +impl<'a> MockEndpoint<'a, QueryKeysEndpoint> { + /// Returns a successful empty response. + pub fn ok(self) -> MatrixMock<'a> { + let mock = self.mock.respond_with(ResponseTemplate::new(200).set_body_json(json!({}))); + + MatrixMock { server: self.server, mock } + } +}