diff --git a/crates/matrix-sdk/src/room/calls.rs b/crates/matrix-sdk/src/room/calls.rs index 0415822c3..49df2d12e 100644 --- a/crates/matrix-sdk/src/room/calls.rs +++ b/crates/matrix-sdk/src/room/calls.rs @@ -34,7 +34,7 @@ pub enum CallError { #[error("Couldn't fetch the remote event: {0}")] Fetch(Box), - /// We tried to decline an event wich is not of type m.rtc.notification. + /// We tried to decline an event which is not of type m.rtc.notification. #[error("You cannot decline this event type.")] BadEventType, diff --git a/crates/matrix-sdk/src/widget/settings/element_call.rs b/crates/matrix-sdk/src/widget/settings/element_call.rs index cb0905c7b..ff33241ef 100644 --- a/crates/matrix-sdk/src/widget/settings/element_call.rs +++ b/crates/matrix-sdk/src/widget/settings/element_call.rs @@ -82,7 +82,8 @@ struct ElementCallParams { /// Defines if a call is encrypted and which encryption system should be used. /// /// This controls the url parameters: `perParticipantE2EE`, `password`. -#[derive(Debug, PartialEq, Default, uniffi::Enum, Clone)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))] +#[derive(Debug, PartialEq, Default, Clone)] pub enum EncryptionSystem { /// Equivalent to the element call url parameter: `perParticipantE2EE=false` /// and no password. @@ -102,7 +103,8 @@ pub enum EncryptionSystem { /// Defines the intent of showing the call. /// /// This controls whether to show or skip the lobby. -#[derive(Debug, PartialEq, Serialize, Default, uniffi::Enum, Clone)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))] +#[derive(Debug, PartialEq, Serialize, Default, Clone)] #[serde(rename_all = "snake_case")] pub enum Intent { #[default] @@ -113,7 +115,8 @@ pub enum Intent { } /// Defines how (if) element-call renders a header. -#[derive(Debug, PartialEq, Serialize, Default, uniffi::Enum, Clone)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))] +#[derive(Debug, PartialEq, Serialize, Default, Clone)] #[serde(rename_all = "snake_case")] pub enum HeaderStyle { /// The normal header with branding. @@ -126,7 +129,8 @@ pub enum HeaderStyle { } /// Types of call notifications. -#[derive(Debug, PartialEq, Serialize, uniffi::Enum, Clone)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))] +#[derive(Debug, PartialEq, Serialize, Clone)] #[serde(rename_all = "snake_case")] pub enum NotificationType { /// The receiving client should display a visual notification. @@ -136,7 +140,8 @@ pub enum NotificationType { } /// Properties to create a new virtual Element Call widget. -#[derive(Debug, Default, uniffi::Record, Clone)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Record))] +#[derive(Debug, Default, Clone)] pub struct VirtualElementCallWidgetOptions { /// The url to the app. /// diff --git a/crates/matrix-sdk/tests/integration/room/calls.rs b/crates/matrix-sdk/tests/integration/room/calls.rs new file mode 100644 index 000000000..9c61fbe17 --- /dev/null +++ b/crates/matrix-sdk/tests/integration/room/calls.rs @@ -0,0 +1,84 @@ +use std::sync::{Arc, Mutex}; + +use matrix_sdk::test_utils::mocks::MatrixMockServer; +use matrix_sdk_test::{async_test, event_factory::EventFactory, JoinedRoomBuilder}; +use ruma::{owned_event_id, room_id, user_id, OwnedUserId}; +use tokio::spawn; + +#[async_test] +async fn test_subscribe_to_decline_call_events() { + let server = MatrixMockServer::new().await; + let client = server.client_builder().build().await; + + let decliners_sequences: Arc>> = Arc::new(Mutex::new(Vec::new())); + let asserted_decliners = vec![user_id!("@bob:matrix.org"), user_id!("@carl:example.com")]; + + let room_id = room_id!("!test:example.org"); + + let notification_event_id = owned_event_id!("$00000:localhost"); + // Initial sync with our test room. + // let room = server.sync_joined_room(&client, room_id).await; + + let f = EventFactory::new(); + server + .sync_room( + &client, + JoinedRoomBuilder::new(room_id).add_timeline_event( + f.call_notify( + "call_id".to_owned(), + ruma::events::call::notify::ApplicationType::Call, + ruma::events::call::notify::NotifyType::Ring, + ruma::events::Mentions::new(), + ) + .sender(&user_id!("@alice:matrix.org")) + .event_id(¬ification_event_id), + ), + ) + .await; + + let room = server.sync_joined_room(&client, room_id).await; + + let to_subscribe_to = notification_event_id.clone(); + let join_handle = spawn({ + let decliners_sequences = Arc::clone(&decliners_sequences); + async move { + let (_drop_guard, mut subscriber) = + room.subscribe_to_call_decline_events(&to_subscribe_to); + + while let Ok(user_id) = subscriber.recv().await { + let mut decliners_sequences = decliners_sequences.lock().unwrap(); + decliners_sequences.push(user_id); + + // When we have received 2 typing notifications, we can stop listening. + if decliners_sequences.len() == 2 { + break; + } + } + } + }); + + let other_notification_event_id = owned_event_id!("$11111:localhost"); + + server + .sync_room( + &client, + JoinedRoomBuilder::new(room_id) + .add_timeline_event( + // declines another call + f.call_decline(&other_notification_event_id) + .sender(&user_id!("@valere:matrix.org")), + ) + .add_timeline_event( + // declines another call + f.call_decline(¬ification_event_id).sender(&user_id!("@bob:matrix.org")), + ) + .add_timeline_event( + // declines another call + f.call_decline(¬ification_event_id).sender(&user_id!("@carl:example.com")), + ), + ) + .await; + + join_handle.await.unwrap(); + assert_eq!(decliners_sequences.lock().unwrap().to_vec(), asserted_decliners); +} diff --git a/crates/matrix-sdk/tests/integration/room/mod.rs b/crates/matrix-sdk/tests/integration/room/mod.rs index 7232afabe..7323ae1b3 100644 --- a/crates/matrix-sdk/tests/integration/room/mod.rs +++ b/crates/matrix-sdk/tests/integration/room/mod.rs @@ -1,6 +1,7 @@ mod attachment; mod beacon; mod beacon_info; +mod calls; mod common; mod joined; mod left; diff --git a/testing/matrix-sdk-test/src/event_factory.rs b/testing/matrix-sdk-test/src/event_factory.rs index e622b939d..7773c571c 100644 --- a/testing/matrix-sdk-test/src/event_factory.rs +++ b/testing/matrix-sdk-test/src/event_factory.rs @@ -73,6 +73,7 @@ use ruma::{ tombstone::RoomTombstoneEventContent, topic::RoomTopicEventContent, }, + rtc::decline::RtcDeclineEventContent, space::{child::SpaceChildEventContent, parent::SpaceParentEventContent}, sticker::StickerEventContent, typing::TypingEventContent, @@ -1013,6 +1014,14 @@ impl EventFactory { self.event(CallNotifyEventContent::new(call_id, application, notify_type, mentions)) } + // Creates a new `org.matrix.msc4310.rtc.decline` event. + pub fn call_decline( + &self, + notification_event_id: &EventId, + ) -> EventBuilder { + self.event(RtcDeclineEventContent::new(notification_event_id)) + } + /// Create a new `m.direct` global account data event. pub fn direct(&self) -> EventBuilder { let mut builder = self.event(DirectEventContent::default());