Skip to content

Commit

Permalink
add integration test for futures.
Browse files Browse the repository at this point in the history
  • Loading branch information
toger5 committed Jul 5, 2024
1 parent 1d3b270 commit 043c9ac
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 21 deletions.
43 changes: 22 additions & 21 deletions crates/matrix-sdk/src/widget/machine/from_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<OwnedRoomId>,
pub(crate) room_id: Option<OwnedRoomId>,
/// 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<OwnedEventId>,
pub(crate) event_id: Option<OwnedEventId>,
/// A token to send/insert the future into the DAG.
pub send_token: Option<String>,
pub(crate) send_token: Option<String>,
/// A token to cancel this future. It will never be send if this is called.
pub cancel_token: Option<String>,
pub(crate) cancel_token: Option<String>,
/// 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<String>,
pub(crate) future_group_id: Option<String>,
/// 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<String>,
pub(crate) refresh_token: Option<String>,
}

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),
Expand All @@ -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<SendEventResponse> for future::send_future_message_event::unstable::Response {
fn into(self) -> SendEventResponse {

impl From<future::send_future_message_event::unstable::Response> 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<SendEventResponse> for future::send_future_state_event::unstable::Response {
fn into(self) -> SendEventResponse {
impl From<future::send_future_state_event::unstable::Response> 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,
}
}
}
111 changes: 111 additions & 0 deletions crates/matrix-sdk/tests/integration/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 043c9ac

Please sign in to comment.