diff --git a/crates/matrix-sdk/src/widget/machine/from_widget.rs b/crates/matrix-sdk/src/widget/machine/from_widget.rs index 1644cd5c15..4aa383c3df 100644 --- a/crates/matrix-sdk/src/widget/machine/from_widget.rs +++ b/crates/matrix-sdk/src/widget/machine/from_widget.rs @@ -134,30 +134,30 @@ pub(super) struct ReadEventResponse { } #[derive(Serialize, Debug)] -pub struct SendEventResponse { +pub(crate) struct SendEventResponse { /// The room id for the send event. - pub room_id: Option, + pub(crate) room_id: Option, /// The event id of the send event. Its optional because if its a future one /// does not get the event_id at this point. - pub event_id: Option, + pub(crate) event_id: Option, /// A token to send/insert the future into the DAG. - pub send_token: Option, + pub(crate) send_token: Option, /// A token to cancel this future. It will never be send if this is called. - pub cancel_token: Option, + pub(crate) cancel_token: Option, /// The `future_group_id` generated for this future. Used to connect /// multiple futures only one of the connected futures will be sent and /// inserted into the DAG. - pub future_group_id: Option, + pub(crate) future_group_id: Option, /// A token used to refresh the timer of the future. This allows /// to implement heartbeat like capabilities. An event is only sent once /// a refresh in the timeout interval is missed. /// /// If the future does not have a timeout this will be `None`. - pub refresh_token: Option, + pub(crate) refresh_token: Option, } impl SendEventResponse { - pub fn from_event_id(event_id: OwnedEventId) -> Self { + pub(crate) fn from_event_id(event_id: OwnedEventId) -> Self { SendEventResponse { room_id: None, event_id: Some(event_id), @@ -167,32 +167,33 @@ impl SendEventResponse { refresh_token: None, } } - pub fn set_room_id(&mut self, room_id: OwnedRoomId) { + pub(crate) fn set_room_id(&mut self, room_id: OwnedRoomId) { self.room_id = Some(room_id); } } -impl Into for future::send_future_message_event::unstable::Response { - fn into(self) -> SendEventResponse { + +impl From for SendEventResponse { + fn from(val: future::send_future_message_event::unstable::Response) -> Self { SendEventResponse { room_id: None, event_id: None, - send_token: Some(self.send_token), - cancel_token: Some(self.cancel_token), - future_group_id: Some(self.future_group_id), - refresh_token: self.refresh_token, + send_token: Some(val.send_token), + cancel_token: Some(val.cancel_token), + future_group_id: Some(val.future_group_id), + refresh_token: val.refresh_token, } } } -impl Into for future::send_future_state_event::unstable::Response { - fn into(self) -> SendEventResponse { +impl From for SendEventResponse { + fn from(val: future::send_future_state_event::unstable::Response) -> Self { SendEventResponse { room_id: None, event_id: None, - send_token: Some(self.send_token), - cancel_token: Some(self.cancel_token), - future_group_id: Some(self.future_group_id), - refresh_token: self.refresh_token, + send_token: Some(val.send_token), + cancel_token: Some(val.cancel_token), + future_group_id: Some(val.future_group_id), + refresh_token: val.refresh_token, } } } diff --git a/crates/matrix-sdk/tests/integration/widget.rs b/crates/matrix-sdk/tests/integration/widget.rs index 9ff2387d28..09b9e81273 100644 --- a/crates/matrix-sdk/tests/integration/widget.rs +++ b/crates/matrix-sdk/tests/integration/widget.rs @@ -600,6 +600,117 @@ async fn send_room_name() { mock_server.verify().await; } +#[async_test] +async fn send_future_room_message() { + let (_, mock_server, driver_handle) = run_test_driver(false).await; + + // let a= "{\"action\":\"send_event\",\"api\":\"fromWidget\",\"data\":{\"content\":{\"body\":\"Message from a widget!\",\"msgtype\":\"m.text\"},\"type\":\"m.room.message\"},\"future_timeout\":1000,\"requestId\":\"send-room-message\",\"widgetId\":\"test-widget\"}"; + + negotiate_capabilities(&driver_handle, json!(["org.matrix.msc2762.send.event:m.room.message"])) + .await; + + Mock::given(method("PUT")) + .and(path_regex( + r"^/_matrix/client/unstable/org.matrix.msc4140/rooms/.*/send_future/m.room.message/.*$", + )) + .respond_with(ResponseTemplate::new(200).set_body_json(json!({ + "future_group_id": "1234", + "send_token": "my_send_token", + "refresh_token":"my_refresh_token", + "cancel_token": "my_cancel_token" + }))) + .expect(1) + .mount(&mock_server) + .await; + + send_request( + &driver_handle, + "send-room-message", + "send_event", + json!({ + "type": "m.room.message", + "content": { + "msgtype": "m.text", + "body": "Message from a widget!", + }, + "future_timeout":1000, + }), + ) + .await; + + // Receive the response + let msg = recv_message(&driver_handle).await; + assert_eq!(msg["api"], "fromWidget"); + assert_eq!(msg["action"], "send_event"); + let future_group_id = msg["response"]["future_group_id"].as_str().unwrap(); + assert_eq!(future_group_id, "1234"); + let cancel_token = msg["response"]["cancel_token"].as_str().unwrap(); + assert_eq!(cancel_token, "my_cancel_token"); + let refresh_token = msg["response"]["refresh_token"].as_str().unwrap(); + assert_eq!(refresh_token, "my_refresh_token"); + let send_token = msg["response"]["send_token"].as_str().unwrap(); + assert_eq!(send_token, "my_send_token"); + + // Make sure the event-sending endpoint was hit exactly once + mock_server.verify().await; +} + +#[async_test] +async fn send_future_state() { + let (_, mock_server, driver_handle) = run_test_driver(false).await; + + negotiate_capabilities( + &driver_handle, + json!(["org.matrix.msc2762.send.state_event:m.room.name#"]), + ) + .await; + + Mock::given(method("PUT")) + .and(path_regex( + r"^/_matrix/client/unstable/org.matrix.msc4140/rooms/.*/state_future/m.room.name/?$", + )) + .respond_with(ResponseTemplate::new(200).set_body_json(json!({ + "future_group_id": "1234", + "send_token": "my_send_token", + "refresh_token":"my_refresh_token", + "cancel_token": "my_cancel_token" + }))) + .expect(1) + .mount(&mock_server) + .await; + + send_request( + &driver_handle, + "send-room-message", + "send_event", + json!({ + "type": "m.room.name", + "state_key": "", + "content": { + "name": "Room Name set by Widget", + }, + "future_timeout":1000, + }), + ) + .await; + + // Receive the response + let msg = recv_message(&driver_handle).await; + assert_eq!(msg["api"], "fromWidget"); + assert_eq!(msg["action"], "send_event"); + let future_group_id = msg["response"]["future_group_id"].as_str().unwrap(); + assert_eq!(future_group_id, "1234"); + let cancel_token = msg["response"]["cancel_token"].as_str().unwrap(); + assert_eq!(cancel_token, "my_cancel_token"); + let refresh_token = msg["response"]["refresh_token"].as_str().unwrap(); + assert_eq!(refresh_token, "my_refresh_token"); + let send_token = msg["response"]["send_token"].as_str().unwrap(); + assert_eq!(send_token, "my_send_token"); + + // Make sure the event-sending endpoint was hit exactly once + mock_server.verify().await; +} + async fn negotiate_capabilities(driver_handle: &WidgetDriverHandle, caps: JsonValue) { { // Receive toWidget capabilities request