Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor the widget tests to use MockMatrixServer #4236

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 121 additions & 4 deletions crates/matrix-sdk/src/test_utils/mocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@ use matrix_sdk_test::{
test_json, InvitedRoomBuilder, JoinedRoomBuilder, KnockedRoomBuilder, LeftRoomBuilder,
SyncResponseBuilder,
};
use ruma::{api::MatrixVersion, device_id, user_id, MxcUri, OwnedEventId, OwnedRoomId, RoomId};
use serde_json::json;
use ruma::{
api::MatrixVersion,
device_id,
events::{MessageLikeEventType, StateEventType},
user_id, MxcUri, OwnedEventId, OwnedRoomId, RoomId,
};
use serde_json::{json, Value};
use wiremock::{
matchers::{body_partial_json, header, method, path, path_regex},
matchers::{body_partial_json, header, method, path, path_regex, query_param},
Mock, MockBuilder, MockGuard, MockServer, Respond, ResponseTemplate, Times,
};

Expand Down Expand Up @@ -316,6 +321,92 @@ impl MatrixMockServer {
MockEndpoint { mock, server: &self.server, endpoint: RoomSendEndpoint }
}

/// Creates a prebuilt mock for sending an event with a specific type in a
/// room.
///
/// Note: works with *any* room.
///
/// Similar to: [mock_room_send]
toger5 marked this conversation as resolved.
Show resolved Hide resolved
///
/// # Examples
///
/// see also [mock_room_send] for more context.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// see also [mock_room_send] for more context.
/// see also [`MatrixMockServer::mock_room_send`] for more context.

///
/// ```
/// # tokio_test::block_on(async {
/// use matrix_sdk::{ruma::{room_id, event_id}, test_utils::mocks::MatrixMockServer};
/// use serde_json::json;
///
/// let mock_server = MatrixMockServer::new().await;
/// let client = mock_server.client_builder().build().await;
///
/// mock_server.mock_room_state_encryption().plain().mount().await;
///
/// let room = mock_server
/// .sync_joined_room(&client, room_id!("!room_id:localhost"))
/// .await;
///
/// let event_id = event_id!("$some_id");
/// mock_server
/// .mock_room_send_for_type("m.room.message".into())
/// .ok(event_id)
/// .expect(1)
/// .mount()
/// .await;
///
/// let responseNotMocked = room.send_raw("m.room.reaction", json!({ "body": "Hello world" })).await;
/// // The `m.room.reaction` event type should not be mocked by the server.
/// assert!(responseNotMocked.is_err());
///
///
/// let response = room.send_raw("m.room.message", json!({ "body": "Hello world" })).await?;
/// // The `m.room.message` event type should be mocked by the server.
/// assert_eq!(
/// event_id,
/// response.event_id,
/// "The event ID we mocked should match the one we received when we sent the event"
/// );
/// # anyhow::Ok(()) });
/// ```
pub fn mock_room_send_for_type(
&self,
event_type: MessageLikeEventType,
) -> MockEndpoint<'_, RoomSendEndpoint> {
let mock = Mock::given(method("PUT"))
.and(path_regex(format!(r"^/_matrix/client/v3/rooms/.*/send/{}", event_type)))
.and(header("authorization", "Bearer 1234"));
MockEndpoint { mock, server: &self.server, endpoint: RoomSendEndpoint }
}

/// Creates a prebuilt mock for sending a state event in a room.
///
/// Similar to: [mock_room_send]
toger5 marked this conversation as resolved.
Show resolved Hide resolved
///
/// Note: works with *any* room.
/// Note: works with *any* event type.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to add an example for this one as well.

pub fn mock_room_state(&self) -> MockEndpoint<'_, RoomSendEndpoint> {
let mock = Mock::given(method("PUT"))
.and(path_regex(r"^/_matrix/client/r0/rooms/.*/state/.*"))
.and(header("authorization", "Bearer 1234"));
MockEndpoint { mock, server: &self.server, endpoint: RoomSendEndpoint }
}

/// Creates a prebuilt mock for sending a state event with a specific type
/// in a room.
///
/// Similar to: [mock_room_send]
toger5 marked this conversation as resolved.
Show resolved Hide resolved
///
/// Note: works with *any* room.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An example would be nice as well, they would have helped you when you first encountered the MatrixMockServer.

pub fn mock_room_state_for_type(
&self,
state_type: StateEventType,
) -> MockEndpoint<'_, RoomSendEndpoint> {
let mock = Mock::given(method("PUT"))
.and(path_regex(format!(r"^/_matrix/client/v3/rooms/.*/state/{}", state_type)))
.and(header("authorization", "Bearer 1234"));
MockEndpoint { mock, server: &self.server, endpoint: RoomSendEndpoint }
}

/// Creates a prebuilt mock for asking whether *a* room is encrypted or not.
///
/// Note: Applies to all rooms.
Expand Down Expand Up @@ -431,6 +522,18 @@ impl MatrixMockServer {
}
}

/// Create a prebuild mock for reading room message with the `/messages`
toger5 marked this conversation as resolved.
Show resolved Hide resolved
/// endpoint.
pub fn mock_room_messages(&self, limit: Option<u32>) -> MockEndpoint<'_, RoomMessagesEndpoint> {
let mut mock = Mock::given(method("GET"))
.and(path_regex(r"^/_matrix/client/v3/rooms/.*/messages$"))
.and(header("authorization", "Bearer 1234"));
if let Some(l) = limit {
mock = mock.and(query_param("limit", l.to_string()));
}
MockEndpoint { mock, server: &self.server, endpoint: RoomMessagesEndpoint {} }
}

/// Create a prebuilt mock for uploading media.
pub fn mock_upload(&self) -> MockEndpoint<'_, UploadEndpoint> {
let mock = Mock::given(method("POST"))
Expand Down Expand Up @@ -757,7 +860,7 @@ impl<'a> MockEndpoint<'a, RoomSendEndpoint> {
/// );
/// # anyhow::Ok(()) });
/// ```
pub fn body_matches_partial_json(self, body: serde_json::Value) -> Self {
pub fn body_matches_partial_json(self, body: Value) -> Self {
Self { mock: self.mock.and(body_partial_json(body)), ..self }
}

Expand Down Expand Up @@ -980,6 +1083,20 @@ impl<'a> MockEndpoint<'a, RoomEventEndpoint> {
}
}

/// A prebuilt mock for the `/messages` endpoint.
pub struct RoomMessagesEndpoint;

/// A prebuilt mock for getting a room messages in a room.
impl<'a> MockEndpoint<'a, RoomMessagesEndpoint> {
/// Returns a messages endpoint that emulates success, i.e. the messages
/// provided as `response` could be retrieved.
pub fn ok(self, response: impl Into<Value>) -> MatrixMock<'a> {
let body: Value = response.into();
let mock = self.mock.respond_with(ResponseTemplate::new(200).set_body_json(body));
MatrixMock { server: self.server, mock }
}
}

/// A prebuilt mock for uploading media.
pub struct UploadEndpoint;

Expand Down
49 changes: 24 additions & 25 deletions crates/matrix-sdk/tests/integration/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,14 @@ use matrix_sdk_test::{async_test, EventBuilder, JoinedRoomBuilder, ALICE, BOB};
use once_cell::sync::Lazy;
use ruma::{
event_id,
events::room::{
member::{MembershipState, RoomMemberEventContent},
message::RoomMessageEventContent,
name::RoomNameEventContent,
topic::RoomTopicEventContent,
events::{
room::{
member::{MembershipState, RoomMemberEventContent},
message::RoomMessageEventContent,
name::RoomNameEventContent,
topic::RoomTopicEventContent,
},
StateEventType,
},
owned_room_id,
serde::JsonObject,
Expand Down Expand Up @@ -335,14 +338,8 @@ async fn test_read_messages_with_msgtype_capabilities() {
"end": "t47409-4357353_219380_26003_2269",
"start": "t392-516_47314_0_7_1_1_1_11444_1"
});
Mock::given(method("GET"))
.and(path_regex(r"^/_matrix/client/v3/rooms/.*/messages$"))
.and(header("authorization", "Bearer 1234"))
.and(query_param("limit", "3"))
.respond_with(ResponseTemplate::new(200).set_body_json(response_json))
.expect(1)
.mount(mock_server.server())
.await;

mock_server.mock_room_messages(Some(3)).ok(response_json).mock_once().mount().await;

// Ask the driver to read messages
send_request(
Expand Down Expand Up @@ -508,11 +505,11 @@ async fn test_send_room_message() {
negotiate_capabilities(&driver_handle, json!(["org.matrix.msc2762.send.event:m.room.message"]))
.await;

Mock::given(method("PUT"))
.and(path_regex(r"^/_matrix/client/v3/rooms/.*/send/m.room.message/.*$"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({ "event_id": "$foobar" })))
.expect(1)
.mount(mock_server.server())
mock_server
.mock_room_send_for_type("m.room.message".into())
.ok(event_id!("$foobar"))
.mock_once()
.mount()
.await;

send_request(
Expand Down Expand Up @@ -549,11 +546,11 @@ async fn test_send_room_name() {
)
.await;

Mock::given(method("PUT"))
.and(path_regex(r"^/_matrix/client/v3/rooms/.*/state/m.room.name/?$"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({ "event_id": "$foobar" })))
.expect(1)
.mount(mock_server.server())
mock_server
.mock_room_state_for_type(StateEventType::RoomName)
.ok(event_id!("$foobar"))
.mock_once()
.mount()
.await;

send_request(
Expand Down Expand Up @@ -594,7 +591,8 @@ async fn test_send_delayed_message_event() {
.await;

Mock::given(method("PUT"))
.and(path_regex(r"^/_matrix/client/v3/rooms/.*/send/m.room.message/.*$"))
.and(path_regex(r"^/_matrix/client/v3/rooms/.*/send/m.room.message/.*"))
.and(query_param("org.matrix.msc4140.delay", "1000"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({
"delay_id": "1234",
})))
Expand Down Expand Up @@ -641,7 +639,8 @@ async fn test_send_delayed_state_event() {
.await;

Mock::given(method("PUT"))
.and(path_regex(r"^/_matrix/client/v3/rooms/.*/state/m.room.name/?$"))
.and(path_regex(r"^/_matrix/client/v3/rooms/.*/state/m.room.name/.*"))
.and(query_param("org.matrix.msc4140.delay", "1000"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({
"delay_id": "1234",
})))
Expand Down
Loading