feat(testing): allow specifying expiration duration in MockedRendezvousServer

Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
This commit is contained in:
Johannes Marbach
2025-11-25 16:25:13 +01:00
committed by Damir Jelić
parent a82ccf1069
commit 4ab12543ce
3 changed files with 79 additions and 24 deletions
@@ -674,7 +674,8 @@ mod test {
#[async_test]
async fn test_grant_login_with_generated_qr_code() {
let server = MatrixMockServer::new().await;
let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await;
let rendezvous_server =
MockedRendezvousServer::new(server.server(), "abcdEFG12345", Duration::MAX).await;
debug!("Set up rendezvous server mock at {}", rendezvous_server.rendezvous_url);
let device_authorization_grant = AuthorizationGrant {
@@ -817,7 +818,8 @@ mod test {
#[async_test]
async fn test_grant_login_with_scanned_qr_code() {
let server = MatrixMockServer::new().await;
let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await;
let rendezvous_server =
MockedRendezvousServer::new(server.server(), "abcdEFG12345", Duration::MAX).await;
debug!("Set up rendezvous server mock at {}", rendezvous_server.rendezvous_url);
let device_authorization_grant = AuthorizationGrant {
@@ -943,7 +945,8 @@ mod test {
#[async_test]
async fn test_grant_login_with_scanned_qr_code_with_homeserver_swap() {
let server = MatrixMockServer::new().await;
let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await;
let rendezvous_server =
MockedRendezvousServer::new(server.server(), "abcdEFG12345", Duration::MAX).await;
debug!("Set up rendezvous server mock at {}", rendezvous_server.rendezvous_url);
let device_authorization_grant = AuthorizationGrant {
@@ -1072,7 +1075,8 @@ mod test {
async fn test_grant_login_with_generated_qr_code_unexpected_message_instead_of_login_protocol()
{
let server = MatrixMockServer::new().await;
let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await;
let rendezvous_server =
MockedRendezvousServer::new(server.server(), "abcdEFG12345", Duration::MAX).await;
debug!("Set up rendezvous server mock at {}", rendezvous_server.rendezvous_url);
server.mock_upload_keys().ok().expect(1).named("upload_keys").mount().await;
@@ -1188,7 +1192,8 @@ mod test {
#[async_test]
async fn test_grant_login_with_scanned_qr_code_unexpected_message_instead_of_login_protocol() {
let server = MatrixMockServer::new().await;
let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await;
let rendezvous_server =
MockedRendezvousServer::new(server.server(), "abcdEFG12345", Duration::MAX).await;
debug!("Set up rendezvous server mock at {}", rendezvous_server.rendezvous_url);
server.mock_upload_keys().ok().expect(1).named("upload_keys").mount().await;
@@ -1290,7 +1295,8 @@ mod test {
#[async_test]
async fn test_grant_login_with_generated_qr_code_device_already_exists() {
let server = MatrixMockServer::new().await;
let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await;
let rendezvous_server =
MockedRendezvousServer::new(server.server(), "abcdEFG12345", Duration::MAX).await;
debug!("Set up rendezvous server mock at {}", rendezvous_server.rendezvous_url);
let device_authorization_grant = AuthorizationGrant {
@@ -1415,7 +1421,8 @@ mod test {
#[async_test]
async fn test_grant_login_with_scanned_qr_code_device_already_exists() {
let server = MatrixMockServer::new().await;
let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await;
let rendezvous_server =
MockedRendezvousServer::new(server.server(), "abcdEFG12345", Duration::MAX).await;
debug!("Set up rendezvous server mock at {}", rendezvous_server.rendezvous_url);
let device_authorization_grant = AuthorizationGrant {
@@ -1525,7 +1532,8 @@ mod test {
#[async_test]
async fn test_grant_login_with_generated_qr_code_device_not_created() {
let server = MatrixMockServer::new().await;
let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await;
let rendezvous_server =
MockedRendezvousServer::new(server.server(), "abcdEFG12345", Duration::MAX).await;
debug!("Set up rendezvous server mock at {}", rendezvous_server.rendezvous_url);
let device_authorization_grant = AuthorizationGrant {
@@ -1660,7 +1668,8 @@ mod test {
#[async_test]
async fn test_grant_login_with_scanned_qr_code_device_not_created() {
let server = MatrixMockServer::new().await;
let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await;
let rendezvous_server =
MockedRendezvousServer::new(server.server(), "abcdEFG12345", Duration::MAX).await;
debug!("Set up rendezvous server mock at {}", rendezvous_server.rendezvous_url);
let device_authorization_grant = AuthorizationGrant {
@@ -484,6 +484,8 @@ impl<'a> LoginWithGeneratedQrCode<'a> {
#[cfg(all(test, not(target_family = "wasm")))]
mod test {
use std::time::Duration;
use assert_matches2::{assert_let, assert_matches};
use futures_util::StreamExt;
use matrix_sdk_base::crypto::types::{SecretsBundle, qr_login::QrCodeModeData};
@@ -583,7 +585,8 @@ mod test {
#[async_test]
async fn test_qr_login() {
let server = MatrixMockServer::new().await;
let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await;
let rendezvous_server =
MockedRendezvousServer::new(server.server(), "abcdEFG12345", Duration::MAX).await;
let (sender, receiver) = tokio::sync::oneshot::channel();
let oauth_server = server.oauth();
@@ -742,7 +745,8 @@ mod test {
#[async_test]
async fn test_generated_qr_login() {
let server = MatrixMockServer::new().await;
let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await;
let rendezvous_server =
MockedRendezvousServer::new(server.server(), "abcdEFG12345", Duration::MAX).await;
let (qr_sender, qr_receiver) = tokio::sync::oneshot::channel();
let (cctx_sender, cctx_receiver) = tokio::sync::oneshot::channel();
@@ -842,7 +846,8 @@ mod test {
#[async_test]
async fn test_generated_qr_login_with_homeserver_swap() {
let server = MatrixMockServer::new().await;
let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await;
let rendezvous_server =
MockedRendezvousServer::new(server.server(), "abcdEFG12345", Duration::MAX).await;
let (qr_sender, qr_receiver) = tokio::sync::oneshot::channel();
let (cctx_sender, cctx_receiver) = tokio::sync::oneshot::channel();
@@ -948,7 +953,8 @@ mod test {
alice_behavior: AliceBehaviour,
) -> Result<(), QRCodeLoginError> {
let server = MatrixMockServer::new().await;
let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await;
let rendezvous_server =
MockedRendezvousServer::new(server.server(), "abcdEFG12345", Duration::MAX).await;
let (sender, receiver) = tokio::sync::oneshot::channel();
let oauth_server = server.oauth();
@@ -1020,7 +1026,8 @@ mod test {
alice_behavior: AliceBehaviour,
) -> Result<(), QRCodeLoginError> {
let server = MatrixMockServer::new().await;
let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await;
let rendezvous_server =
MockedRendezvousServer::new(server.server(), "abcdEFG12345", Duration::MAX).await;
let (qr_sender, qr_receiver) = tokio::sync::oneshot::channel();
let (cctx_sender, cctx_receiver) = tokio::sync::oneshot::channel();
@@ -1239,7 +1246,8 @@ mod test {
#[async_test]
async fn test_device_authorization_endpoint_missing() {
let server = MatrixMockServer::new().await;
let rendezvous_server = MockedRendezvousServer::new(server.server(), "abcdEFG12345").await;
let rendezvous_server =
MockedRendezvousServer::new(server.server(), "abcdEFG12345", Duration::MAX).await;
let (sender, receiver) = tokio::sync::oneshot::channel();
let oauth_server = server.oauth();
@@ -229,14 +229,18 @@ impl EstablishedSecureChannel {
#[cfg(all(test, not(target_family = "wasm")))]
pub(super) mod test {
use std::sync::{
Arc, Mutex,
atomic::{AtomicU8, Ordering},
use std::{
sync::{
Arc, Mutex,
atomic::{AtomicU8, Ordering},
},
time::Duration,
};
use matrix_sdk_base::crypto::types::qr_login::QrCodeMode;
use matrix_sdk_common::executor::spawn;
use matrix_sdk_test::async_test;
use ruma::time::Instant;
use serde_json::json;
use similar_asserts::assert_eq;
use url::Url;
@@ -252,7 +256,9 @@ pub(super) mod test {
pub struct MockedRendezvousServer {
pub homeserver_url: Url,
pub rendezvous_url: Url,
expiration: Duration,
content: Arc<Mutex<Option<String>>>,
created: Arc<Mutex<Option<Instant>>>,
etag: Arc<AtomicU8>,
post_guard: MockGuard,
put_guard: MockGuard,
@@ -260,8 +266,9 @@ pub(super) mod test {
}
impl MockedRendezvousServer {
pub async fn new(server: &MockServer, location: &str) -> Self {
pub async fn new(server: &MockServer, location: &str, expiration: Duration) -> Self {
let content: Arc<Mutex<Option<String>>> = Mutex::default().into();
let created: Arc<Mutex<Option<Instant>>> = Mutex::default().into();
let etag = Arc::new(AtomicU8::new(0));
let homeserver_url = Url::parse(&server.uri())
@@ -275,7 +282,9 @@ pub(super) mod test {
.register_as_scoped(
Mock::given(method("POST"))
.and(path("/_matrix/client/unstable/org.matrix.msc4108/rendezvous"))
.respond_with(
.respond_with({
*created.lock().unwrap() = Some(Instant::now());
ResponseTemplate::new(200)
.append_header("X-Max-Bytes", "10240")
.append_header("ETag", "1")
@@ -283,8 +292,8 @@ pub(super) mod test {
.append_header("Last-Modified", "Wed, 07 Sep 2022 14:27:51 GMT")
.set_body_json(json!({
"url": rendezvous_url,
})),
),
}))
}),
)
.await;
@@ -292,9 +301,18 @@ pub(super) mod test {
.register_as_scoped(
Mock::given(method("PUT")).and(path("/abcdEFG12345")).respond_with({
let content = content.clone();
let created = created.clone();
let etag = etag.clone();
move |request: &wiremock::Request| {
// Fail the request if the session has expired.
if created.lock().unwrap().unwrap().elapsed() > expiration {
return ResponseTemplate::new(404).set_body_json(json!({
"errcode": "M_NOT_FOUND",
"error": "This rendezvous session does not exist.",
}));
}
*content.lock().unwrap() =
Some(String::from_utf8(request.body.clone()).unwrap());
let current_etag = etag.fetch_add(1, Ordering::SeqCst);
@@ -312,9 +330,18 @@ pub(super) mod test {
.register_as_scoped(
Mock::given(method("GET")).and(path("/abcdEFG12345")).respond_with({
let content = content.clone();
let created = created.clone();
let etag = etag.clone();
move |request: &wiremock::Request| {
// Fail the request if the session has expired.
if created.lock().unwrap().unwrap().elapsed() > expiration {
return ResponseTemplate::new(404).set_body_json(json!({
"errcode": "M_NOT_FOUND",
"error": "This rendezvous session does not exist.",
}));
}
let requested_etag = request.headers.get("if-none-match").map(|etag| {
str::parse::<u8>(std::str::from_utf8(etag.as_bytes()).unwrap())
.unwrap()
@@ -344,14 +371,25 @@ pub(super) mod test {
)
.await;
Self { content, etag, post_guard, put_guard, get_guard, homeserver_url, rendezvous_url }
Self {
expiration,
content,
created,
etag,
post_guard,
put_guard,
get_guard,
homeserver_url,
rendezvous_url,
}
}
}
#[async_test]
async fn test_creation() {
let server = MockServer::start().await;
let rendezvous_server = MockedRendezvousServer::new(&server, "abcdEFG12345").await;
let rendezvous_server =
MockedRendezvousServer::new(&server, "abcdEFG12345", Duration::MAX).await;
let client = HttpClient::new(reqwest::Client::new(), Default::default());
let alice = SecureChannel::reciprocate(client, &rendezvous_server.homeserver_url)