mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-08-07 05:22:31 -04:00
test: add the start of an integration test for room history sharing
This is only a partial test, since we haven't yet implemented the receiver side of the history-sharing messages.
This commit is contained in:
1 parent
f11158ab6c
commit
9ef1a040dd
2 files changed
+140
-8
No files matched your search
@@ -16,6 +16,7 @@ use matrix_sdk::{
|
||||
RoomId,
|
||||
},
|
||||
sliding_sync::VersionBuilder,
|
||||
sync::SyncResponse,
|
||||
Client, ClientBuilder, Room,
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
@@ -185,7 +186,7 @@ impl SyncTokenAwareClient {
|
||||
Self { client, token: Arc::new(None.into()) }
|
||||
}
|
||||
|
||||
pub async fn sync_once(&self) -> Result<()> {
|
||||
pub async fn sync_once(&self) -> Result<SyncResponse> {
|
||||
let mut settings = SyncSettings::default().timeout(Duration::from_secs(1));
|
||||
|
||||
let token = { self.token.lock().unwrap().clone() };
|
||||
@@ -197,9 +198,9 @@ impl SyncTokenAwareClient {
|
||||
|
||||
let mut prev_token = self.token.lock().unwrap();
|
||||
if prev_token.as_ref() != Some(&response.next_batch) {
|
||||
*prev_token = Some(response.next_batch);
|
||||
*prev_token = Some(response.next_batch.clone());
|
||||
}
|
||||
Ok(())
|
||||
Ok(response)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::{
|
||||
future::IntoFuture,
|
||||
sync::{Arc, Mutex},
|
||||
time::Duration,
|
||||
};
|
||||
@@ -9,7 +10,7 @@ use assert_matches2::assert_let;
|
||||
use assign::assign;
|
||||
use matrix_sdk::{
|
||||
assert_next_eq_with_timeout,
|
||||
crypto::{format_emojis, SasState},
|
||||
crypto::{format_emojis, SasState, UserDevices},
|
||||
encryption::{
|
||||
backups::BackupState,
|
||||
recovery::{Recovery, RecoveryState},
|
||||
@@ -19,7 +20,10 @@ use matrix_sdk::{
|
||||
BackupDownloadStrategy, EncryptionSettings, LocalTrust,
|
||||
},
|
||||
ruma::{
|
||||
api::client::room::create_room::v3::Request as CreateRoomRequest,
|
||||
api::client::{
|
||||
message::send_message_event,
|
||||
room::create_room::v3::{Request as CreateRoomRequest, RoomPreset},
|
||||
},
|
||||
events::{
|
||||
key::verification::{request::ToDeviceKeyVerificationRequestEvent, VerificationMethod},
|
||||
room::message::{
|
||||
@@ -27,9 +31,10 @@ use matrix_sdk::{
|
||||
SyncRoomMessageEvent,
|
||||
},
|
||||
secret_storage::secret::SecretEventContent,
|
||||
GlobalAccountDataEventType, OriginalSyncMessageLikeEvent,
|
||||
GlobalAccountDataEventType, MessageLikeEventType, OriginalSyncMessageLikeEvent,
|
||||
},
|
||||
OwnedEventId,
|
||||
serde::Raw,
|
||||
OwnedEventId, TransactionId, UserId,
|
||||
},
|
||||
timeout::timeout,
|
||||
Client,
|
||||
@@ -39,7 +44,7 @@ use matrix_sdk_ui::{
|
||||
sync_service::SyncService,
|
||||
};
|
||||
use similar_asserts::assert_eq;
|
||||
use tracing::{debug, warn};
|
||||
use tracing::{debug, info, warn, Instrument};
|
||||
|
||||
use crate::helpers::{SyncTokenAwareClient, TestClientBuilder};
|
||||
|
||||
@@ -1175,3 +1180,129 @@ async fn test_recovery_disabling_deletes_secret_storage_secrets() -> Result<()>
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// When we invite another user to a room with "joined" history visibility, we
|
||||
/// share the encryption history.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
|
||||
async fn test_history_share_on_invite() -> Result<()> {
|
||||
let alice_span = tracing::info_span!("alice");
|
||||
let bob_span = tracing::info_span!("bob");
|
||||
|
||||
let encryption_settings =
|
||||
EncryptionSettings { auto_enable_cross_signing: true, ..Default::default() };
|
||||
|
||||
let alice = TestClientBuilder::new("alice")
|
||||
.use_sqlite()
|
||||
.encryption_settings(encryption_settings)
|
||||
.build()
|
||||
.await?;
|
||||
|
||||
let sync_service_span = tracing::info_span!(parent: &alice_span, "sync_service");
|
||||
let alice_sync_service = Arc::new(
|
||||
SyncService::builder(alice.clone())
|
||||
.with_parent_span(sync_service_span)
|
||||
.build()
|
||||
.await
|
||||
.expect("Could not build alice sync service"),
|
||||
);
|
||||
|
||||
alice.encryption().wait_for_e2ee_initialization_tasks().await;
|
||||
alice_sync_service.start().await;
|
||||
|
||||
let bob = SyncTokenAwareClient::new(
|
||||
TestClientBuilder::new("bob").encryption_settings(encryption_settings).build().await?,
|
||||
);
|
||||
|
||||
{
|
||||
// Alice and Bob share an encrypted room
|
||||
// TODO: get rid of all of this: history sharing should work even if Bob and
|
||||
// Alice do not share a room
|
||||
let alice_shared_room = alice
|
||||
.create_room(assign!(CreateRoomRequest::new(), {preset: Some(RoomPreset::PublicChat)}))
|
||||
.await?;
|
||||
let shared_room_id = alice_shared_room.room_id();
|
||||
alice_shared_room.enable_encryption().await?;
|
||||
bob.join_room_by_id(shared_room_id)
|
||||
.instrument(bob_span.clone())
|
||||
.await
|
||||
.expect("Bob should have joined the room");
|
||||
|
||||
// Bob sends a message to trigger another sync from Alice, which causes her to
|
||||
// send out the outgoing requests
|
||||
//
|
||||
// FIXME: this appears to be needed due to a bug in the sliding sync client,
|
||||
// which means it does not send out outgoing requests caused by a
|
||||
// /sync response
|
||||
let request = send_message_event::v3::Request::new_raw(
|
||||
shared_room_id.to_owned(),
|
||||
TransactionId::new(),
|
||||
MessageLikeEventType::Message,
|
||||
Raw::new(&RoomMessageEventContent::text_plain("")).unwrap().cast(),
|
||||
);
|
||||
bob.send(request).into_future().instrument(bob_span.clone()).await?;
|
||||
|
||||
// Sanity check: Both users see the others' device
|
||||
async fn devices_seen(client: &Client, other: &UserId) -> UserDevices {
|
||||
client
|
||||
.olm_machine_for_testing()
|
||||
.await
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get_user_devices(other, Some(Duration::from_secs(1)))
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
timeout(
|
||||
async {
|
||||
loop {
|
||||
let bob_devices = devices_seen(&alice, bob.user_id().unwrap()).await;
|
||||
if bob_devices.devices().count() >= 1 {
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
Duration::from_secs(30), // This can take quite a while to happen on the CI runners.
|
||||
)
|
||||
.await
|
||||
.expect("Alice did not see bob's device");
|
||||
|
||||
bob.sync_once().instrument(bob_span.clone()).await?;
|
||||
let alice_devices = devices_seen(&bob, alice.user_id().unwrap()).await;
|
||||
assert_eq!(alice_devices.devices().count(), 1, "Bob did not see Alice's device");
|
||||
}
|
||||
|
||||
// Alice creates a room ...
|
||||
let alice_room = alice
|
||||
.create_room(assign!(CreateRoomRequest::new(), {
|
||||
preset: Some(RoomPreset::PublicChat),
|
||||
}))
|
||||
.await?;
|
||||
alice_room.enable_encryption().await?;
|
||||
|
||||
info!(room_id = ?alice_room.room_id(), "Alice has created and enabled encryption in the room");
|
||||
|
||||
// ... and sends a message
|
||||
alice_room
|
||||
.send(RoomMessageEventContent::text_plain("Hello Bob"))
|
||||
.await
|
||||
.expect("We should be able to send a message to the room");
|
||||
|
||||
// Alice invites Bob to the room
|
||||
// TODO: invite Bob rather than just call `share_history`
|
||||
alice_room.share_history(bob.user_id().unwrap()).await?;
|
||||
|
||||
let bob_response = bob.sync_once().instrument(bob_span.clone()).await?;
|
||||
|
||||
// Bob should have received a to-device event with the payload
|
||||
assert_eq!(bob_response.to_device.len(), 1);
|
||||
let to_device_event = &bob_response.to_device[0];
|
||||
assert_eq!(
|
||||
to_device_event.get_field::<String>("type").unwrap().unwrap(),
|
||||
"io.element.msc4268.room_key_bundle"
|
||||
);
|
||||
|
||||
// TODO: ensure Bob can decrypt the content
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in new issue
Block a user