From 14cf923361e8f6dda91b0bcc2a33eba2e71917d2 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 19 Oct 2023 12:38:42 +0200 Subject: [PATCH] widget: Add tests for event reading requests --- .../src/widget/machine/tests/capabilities.rs | 2 +- .../src/widget/machine/tests/error.rs | 56 ++++++++++- crates/matrix-sdk/tests/integration/widget.rs | 96 ++++++++++++++----- 3 files changed, 126 insertions(+), 28 deletions(-) diff --git a/crates/matrix-sdk/src/widget/machine/tests/capabilities.rs b/crates/matrix-sdk/src/widget/machine/tests/capabilities.rs index cf93854a6..1ec48c454 100644 --- a/crates/matrix-sdk/src/widget/machine/tests/capabilities.rs +++ b/crates/matrix-sdk/src/widget/machine/tests/capabilities.rs @@ -62,7 +62,7 @@ fn machine_can_request_capabilities_on_content_load() { assert_capabilities_dance(&mut machine, &mut actions_recv); } -fn assert_capabilities_dance( +pub(super) fn assert_capabilities_dance( machine: &mut WidgetMachine, actions_recv: &mut UnboundedReceiver, ) { diff --git a/crates/matrix-sdk/src/widget/machine/tests/error.rs b/crates/matrix-sdk/src/widget/machine/tests/error.rs index 3f29c4662..f9e20723c 100644 --- a/crates/matrix-sdk/src/widget/machine/tests/error.rs +++ b/crates/matrix-sdk/src/widget/machine/tests/error.rs @@ -15,7 +15,7 @@ use assert_matches::assert_matches; use serde_json::json; -use super::{parse_msg, WIDGET_ID}; +use super::{capabilities::assert_capabilities_dance, parse_msg, WIDGET_ID}; use crate::widget::machine::{Action, IncomingMessage, WidgetMachine}; #[test] @@ -45,3 +45,57 @@ fn machine_sends_error_for_unknown_request() { assert_eq!(msg["data"], json!({ "some": "field" })); assert!(msg["response"]["error"]["message"].is_string()); } + +#[test] +fn read_messages_without_capabilities() { + let (mut machine, mut actions_recv) = WidgetMachine::new(WIDGET_ID.to_owned(), true); + + machine.process(IncomingMessage::WidgetMessage(json_string!({ + "api": "fromWidget", + "widgetId": WIDGET_ID, + "requestId": "get-me-some-messages", + "action": "org.matrix.msc2876.read_events", + "data": { + "type": "m.room.message", + }, + }))); + + let action = actions_recv.try_recv().unwrap(); + let msg = assert_matches!(action, Action::SendToWidget(msg) => msg); + let (msg, request_id) = parse_msg(&msg); + assert_eq!(request_id, "get-me-some-messages"); + assert_eq!(msg["api"], "fromWidget"); + assert_eq!(msg["action"], "org.matrix.msc2876.read_events"); + assert_eq!( + msg["response"]["error"]["message"].as_str().unwrap(), + "Received read event request before capabilities were negotiated" + ); +} + +#[test] +fn read_messages_not_yet_supported() { + let (mut machine, mut actions_recv) = WidgetMachine::new(WIDGET_ID.to_owned(), false); + + assert_capabilities_dance(&mut machine, &mut actions_recv); + + machine.process(IncomingMessage::WidgetMessage(json_string!({ + "api": "fromWidget", + "widgetId": WIDGET_ID, + "requestId": "get-me-some-messages", + "action": "org.matrix.msc2876.read_events", + "data": { + "type": "m.room.message", + }, + }))); + + let action = actions_recv.try_recv().unwrap(); + let msg = assert_matches!(action, Action::SendToWidget(msg) => msg); + let (msg, request_id) = parse_msg(&msg); + assert_eq!(request_id, "get-me-some-messages"); + assert_eq!(msg["api"], "fromWidget"); + assert_eq!(msg["action"], "org.matrix.msc2876.read_events"); + assert_eq!( + msg["response"]["error"]["message"].as_str().unwrap(), + "Reading of message events is not yet supported" + ); +} diff --git a/crates/matrix-sdk/tests/integration/widget.rs b/crates/matrix-sdk/tests/integration/widget.rs index 0686e3471..be8baaf72 100644 --- a/crates/matrix-sdk/tests/integration/widget.rs +++ b/crates/matrix-sdk/tests/integration/widget.rs @@ -28,7 +28,7 @@ use matrix_sdk_test::{async_test, JoinedRoomBuilder, SyncResponseBuilder}; use once_cell::sync::Lazy; use ruma::{owned_room_id, serde::JsonObject, OwnedRoomId}; use serde::Serialize; -use serde_json::json; +use serde_json::{json, Value as JsonValue}; use tracing::error; use wiremock::{ matchers::{header, method, path_regex, query_param}, @@ -174,31 +174,11 @@ async fn read_messages() { assert!(msg["data"].as_object().unwrap().is_empty()); } - let caps = json!(["org.matrix.msc2762.receive.event:m.room.message"]); - - { - // Receive toWidget capabilities request - let msg = recv_message(&driver_handle).await; - assert_eq!(msg["api"], "toWidget"); - assert_eq!(msg["action"], "capabilities"); - let data = &msg["data"]; - let request_id = msg["requestId"].as_str().unwrap(); - - // Answer with caps we want - send_response(&driver_handle, request_id, "capabilities", data, &caps).await; - } - - { - // Receive a "request" with the capabilities we were actually granted (wtf?) - let msg = recv_message(&driver_handle).await; - assert_eq!(msg["api"], "toWidget"); - assert_eq!(msg["action"], "notify_capabilities"); - assert_eq!(msg["data"], json!({ "requested": caps, "approved": caps })); - let request_id = msg["requestId"].as_str().unwrap(); - - // ACK the request - send_response(&driver_handle, request_id, "notify_capabilities", caps, json!({})).await; - } + negotiate_capabilities( + &driver_handle, + json!(["org.matrix.msc2762.receive.event:m.room.message"]), + ) + .await; // No messages from the driver assert_matches!(recv_message(&driver_handle).now_or_never(), None); @@ -268,3 +248,67 @@ async fn read_messages() { mock_server.verify().await; } + +#[async_test] +async fn read_room_members() { + let (mock_server, driver_handle) = run_test_driver(false).await; + + negotiate_capabilities( + &driver_handle, + json!(["org.matrix.msc2762.receive.state_event:m.room.member"]), + ) + .await; + + // No messages from the driver + assert_matches!(recv_message(&driver_handle).now_or_never(), None); + + { + // The read-events request is fulfilled from the state store + drop(mock_server); + + // Ask the driver to read state events + send_request( + &driver_handle, + "2-read-messages", + "org.matrix.msc2876.read_events", + json!({ "type": "m.room.member", "state_key": true }), + ) + .await; + + // Receive the response + let msg = recv_message(&driver_handle).await; + assert_eq!(msg["api"], "fromWidget"); + assert_eq!(msg["action"], "org.matrix.msc2876.read_events"); + let events = msg["response"]["events"].as_array().unwrap(); + + // No useful data in the state store, that's fine for this test + // (we just want to know that a successful response is generated) + assert_eq!(events.len(), 0); + } +} + +async fn negotiate_capabilities(driver_handle: &WidgetDriverHandle, caps: JsonValue) { + { + // Receive toWidget capabilities request + let msg = recv_message(driver_handle).await; + assert_eq!(msg["api"], "toWidget"); + assert_eq!(msg["action"], "capabilities"); + let data = &msg["data"]; + let request_id = msg["requestId"].as_str().unwrap(); + + // Answer with caps we want + send_response(driver_handle, request_id, "capabilities", data, &caps).await; + } + + { + // Receive notification with granted capabilities + let msg = recv_message(driver_handle).await; + assert_eq!(msg["api"], "toWidget"); + assert_eq!(msg["action"], "notify_capabilities"); + assert_eq!(msg["data"], json!({ "requested": caps, "approved": caps })); + let request_id = msg["requestId"].as_str().unwrap(); + + // ACK the notification + send_response(driver_handle, request_id, "notify_capabilities", caps, json!({})).await; + } +}