diff --git a/crates/matrix-sdk/src/encryption/backups/mod.rs b/crates/matrix-sdk/src/encryption/backups/mod.rs index bf64e580b42..d0d0ad43e59 100644 --- a/crates/matrix-sdk/src/encryption/backups/mod.rs +++ b/crates/matrix-sdk/src/encryption/backups/mod.rs @@ -1010,11 +1010,11 @@ mod test { use serde_json::json; use wiremock::{ matchers::{header, method, path}, - Mock, MockGuard, MockServer, ResponseTemplate, + Mock, MockServer, ResponseTemplate, }; use super::*; - use crate::test_utils::logged_in_client; + use crate::test_utils::{logged_in_client, mocks::MatrixMockServer}; fn room_key() -> ExportedRoomKey { let json = json!({ @@ -1120,10 +1120,10 @@ mod test { #[async_test] async fn test_when_a_backup_exists_then_exists_on_server_returns_true() { - let server = MockServer::start().await; - let client = logged_in_client(Some(server.uri())).await; + let server = MatrixMockServer::new().await; + let client = server.client_builder().build().await; - let _scope = mock_backup_exists(&server).await; + server.mock_room_keys_version().exists().expect(1).mount().await; let exists = client .encryption() @@ -1133,16 +1133,14 @@ mod test { .expect("We should be able to check if backups exist on the server"); assert!(exists, "We should deduce that a backup exists on the server"); - - server.verify().await; } #[async_test] async fn test_when_no_backup_exists_then_exists_on_server_returns_false() { - let server = MockServer::start().await; - let client = logged_in_client(Some(server.uri())).await; + let server = MatrixMockServer::new().await; + let client = server.client_builder().build().await; - let _scope = mock_backup_none(&server).await; + server.mock_room_keys_version().none().expect(1).mount().await; let exists = client .encryption() @@ -1152,17 +1150,16 @@ mod test { .expect("We should be able to check if backups exist on the server"); assert!(!exists, "We should deduce that no backup exists on the server"); - - server.verify().await; } #[async_test] async fn test_when_server_returns_an_error_then_exists_on_server_returns_an_error() { - let server = MockServer::start().await; - let client = logged_in_client(Some(server.uri())).await; + let server = MatrixMockServer::new().await; + let client = server.client_builder().build().await; { - let _scope = mock_backup_too_many_requests(&server).await; + let _scope = + server.mock_room_keys_version().error429().expect(1).mount_as_scoped().await; client.encryption().backups().exists_on_server().await.expect_err( "If the /version endpoint returns a non 404 error we should throw an error", @@ -1170,14 +1167,13 @@ mod test { } { - let _scope = mock_backup_404(&server); + let _scope = + server.mock_room_keys_version().error404().expect(1).mount_as_scoped().await; client.encryption().backups().exists_on_server().await.expect_err( "If the /version endpoint returns a non-Matrix 404 error we should throw an error", ); } - - server.verify().await; } #[async_test] @@ -1254,60 +1250,4 @@ mod test { server.verify().await; } - - async fn mock_backup_exists(server: &MockServer) -> MockGuard { - Mock::given(method("GET")) - .and(path("_matrix/client/r0/room_keys/version")) - .and(header("authorization", "Bearer 1234")) - .respond_with(ResponseTemplate::new(200).set_body_json(json!({ - "algorithm": "m.megolm_backup.v1.curve25519-aes-sha2", - "auth_data": { - "public_key": "abcdefg", - "signatures": {}, - }, - "count": 42, - "etag": "anopaquestring", - "version": "1", - }))) - .expect(1) - .mount_as_scoped(server) - .await - } - - async fn mock_backup_none(server: &MockServer) -> MockGuard { - Mock::given(method("GET")) - .and(path("_matrix/client/r0/room_keys/version")) - .and(header("authorization", "Bearer 1234")) - .respond_with(ResponseTemplate::new(404).set_body_json(json!({ - "errcode": "M_NOT_FOUND", - "error": "No current backup version" - }))) - .expect(1) - .mount_as_scoped(server) - .await - } - - async fn mock_backup_too_many_requests(server: &MockServer) -> MockGuard { - Mock::given(method("GET")) - .and(path("_matrix/client/r0/room_keys/version")) - .and(header("authorization", "Bearer 1234")) - .respond_with(ResponseTemplate::new(429).set_body_json(json!({ - "errcode": "M_LIMIT_EXCEEDED", - "error": "Too many requests", - "retry_after_ms": 2000 - }))) - .expect(1) - .mount_as_scoped(server) - .await - } - - async fn mock_backup_404(server: &MockServer) -> MockGuard { - Mock::given(method("GET")) - .and(path("_matrix/client/r0/room_keys/version")) - .and(header("authorization", "Bearer 1234")) - .respond_with(ResponseTemplate::new(404)) - .expect(1) - .mount_as_scoped(server) - .await - } } diff --git a/crates/matrix-sdk/src/test_utils/mocks.rs b/crates/matrix-sdk/src/test_utils/mocks.rs index 6774102f227..46981c4b6c5 100644 --- a/crates/matrix-sdk/src/test_utils/mocks.rs +++ b/crates/matrix-sdk/src/test_utils/mocks.rs @@ -560,6 +560,36 @@ impl MatrixMockServer { let mock = Mock::given(method("POST")).and(path_regex(r"/_matrix/client/v3/publicRooms")); MockEndpoint { mock, server: &self.server, endpoint: PublicRoomsEndpoint } } + + /// Create a prebuilt mock for fetching information about key storage + /// backups. + /// + /// # Examples + /// + /// ``` + /// # #[cfg(feature = "e2e-encryption")] + /// # { + /// # tokio_test::block_on(async { + /// use matrix_sdk::test_utils::mocks::MatrixMockServer; + /// + /// let mock_server = MatrixMockServer::new().await; + /// let client = mock_server.client_builder().build().await; + /// + /// mock_server.mock_room_keys_version().exists().expect(1).mount().await; + /// + /// let exists = + /// client.encryption().backups().exists_on_server().await.unwrap(); + /// + /// assert!(exists); + /// # }); + /// # } + /// ``` + pub fn mock_room_keys_version(&self) -> MockEndpoint<'_, RoomKeysVersionEndpoint> { + let mock = Mock::given(method("GET")) + .and(path_regex(r"_matrix/client/v3/room_keys/version")) + .and(header("authorization", "Bearer 1234")); + MockEndpoint { mock, server: &self.server, endpoint: RoomKeysVersionEndpoint } + } } /// Parameter to [`MatrixMockServer::sync_room`]. @@ -1503,3 +1533,48 @@ impl<'a> MockEndpoint<'a, PublicRoomsEndpoint> { MatrixMock { server: self.server, mock } } } + +/// A prebuilt mock for `room_keys/version`: storage ("backup") of room keys. +pub struct RoomKeysVersionEndpoint; + +impl<'a> MockEndpoint<'a, RoomKeysVersionEndpoint> { + /// Returns an endpoint that says there is a single room keys backup + pub fn exists(self) -> MatrixMock<'a> { + let mock = self.mock.respond_with(ResponseTemplate::new(200).set_body_json(json!({ + "algorithm": "m.megolm_backup.v1.curve25519-aes-sha2", + "auth_data": { + "public_key": "abcdefg", + "signatures": {}, + }, + "count": 42, + "etag": "anopaquestring", + "version": "1", + }))); + MatrixMock { server: self.server, mock } + } + + /// Returns an endpoint that says there is no room keys backup + pub fn none(self) -> MatrixMock<'a> { + let mock = self.mock.respond_with(ResponseTemplate::new(404).set_body_json(json!({ + "errcode": "M_NOT_FOUND", + "error": "No current backup version" + }))); + MatrixMock { server: self.server, mock } + } + + /// Returns an endpoint that 429 errors when we get it + pub fn error429(self) -> MatrixMock<'a> { + let mock = self.mock.respond_with(ResponseTemplate::new(429).set_body_json(json!({ + "errcode": "M_LIMIT_EXCEEDED", + "error": "Too many requests", + "retry_after_ms": 2000 + }))); + MatrixMock { server: self.server, mock } + } + + /// Returns an endpoint that 404 errors when we get it + pub fn error404(self) -> MatrixMock<'a> { + let mock = self.mock.respond_with(ResponseTemplate::new(404)); + MatrixMock { server: self.server, mock } + } +}