Skip to content

Commit 14c6dcc

Browse files
committed
test(sdk): add a mocking endpoing for listing relations and test Room::relations
1 parent ace0026 commit 14c6dcc

File tree

1 file changed

+127
-1
lines changed
  • crates/matrix-sdk/src/test_utils/mocks

1 file changed

+127
-1
lines changed

crates/matrix-sdk/src/test_utils/mocks/mod.rs

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ use wiremock::{
5050
pub mod oauth;
5151

5252
use super::client::MockClientBuilder;
53-
use crate::{Client, OwnedServerName, Room};
53+
use crate::{room::IncludeRelations, Client, OwnedServerName, Room};
5454

5555
/// A [`wiremock`] [`MockServer`] along with useful methods to help mocking
5656
/// Matrix client-server API endpoints easily.
@@ -1009,6 +1009,13 @@ impl MatrixMockServer {
10091009
Mock::given(method("GET")).and(path_regex(r"^/_matrix/client/v1/rooms/.*/threads$"));
10101010
self.mock_endpoint(mock, RoomThreadsEndpoint).expect_default_access_token()
10111011
}
1012+
1013+
/// Create a prebuilt mock for the endpoint used to get the related events.
1014+
pub fn mock_room_relations(&self) -> MockEndpoint<'_, RoomRelationsEndpoint> {
1015+
// Routing happens in the final method ok(), since it can get complicated.
1016+
let mock = Mock::given(method("GET"));
1017+
self.mock_endpoint(mock, RoomRelationsEndpoint::default()).expect_default_access_token()
1018+
}
10121019
}
10131020

10141021
/// Parameter to [`MatrixMockServer::sync_room`].
@@ -2601,3 +2608,122 @@ impl<'a> MockEndpoint<'a, RoomThreadsEndpoint> {
26012608
})))
26022609
}
26032610
}
2611+
2612+
/// A prebuilt mock for a `GET /rooms/{roomId}/relations/{eventId}` family of
2613+
/// requests.
2614+
#[derive(Default)]
2615+
pub struct RoomRelationsEndpoint {
2616+
event_id: Option<OwnedEventId>,
2617+
spec: Option<IncludeRelations>,
2618+
}
2619+
2620+
impl<'a> MockEndpoint<'a, RoomRelationsEndpoint> {
2621+
/// Expects an optional `from` to be set on the request.
2622+
pub fn match_from(self, from: &str) -> Self {
2623+
Self { mock: self.mock.and(query_param("from", from)), ..self }
2624+
}
2625+
2626+
/// Expects an optional `limit` to be set on the request.
2627+
pub fn match_limit(self, limit: u32) -> Self {
2628+
Self { mock: self.mock.and(query_param("limit", limit.to_string())), ..self }
2629+
}
2630+
2631+
/// Match the given subrequest, according to the given specification.
2632+
pub fn match_subrequest(mut self, spec: IncludeRelations) -> Self {
2633+
self.endpoint.spec = Some(spec);
2634+
self
2635+
}
2636+
2637+
/// Expects the request to match a specific event id.
2638+
pub fn match_target_event(mut self, event_id: OwnedEventId) -> Self {
2639+
self.endpoint.event_id = Some(event_id);
2640+
self
2641+
}
2642+
2643+
/// Returns a successful response with some optional events and pagination
2644+
/// tokens.
2645+
pub fn ok(mut self, response: RoomRelationsResponseTemplate) -> MatrixMock<'a> {
2646+
// Escape the leading $ to not confuse the regular expression engine.
2647+
let event_spec = self
2648+
.endpoint
2649+
.event_id
2650+
.take()
2651+
.map(|event_id| event_id.as_str().replace("$", "\\$"))
2652+
.unwrap_or_else(|| ".*".to_owned());
2653+
2654+
match self.endpoint.spec.take() {
2655+
Some(IncludeRelations::RelationsOfType(rel_type)) => {
2656+
self.mock = self.mock.and(path_regex(format!(
2657+
r"^/_matrix/client/v1/rooms/.*/relations/{}/{}$",
2658+
event_spec, rel_type
2659+
)));
2660+
}
2661+
Some(IncludeRelations::RelationsOfTypeAndEventType(rel_type, event_type)) => {
2662+
self.mock = self.mock.and(path_regex(format!(
2663+
r"^/_matrix/client/v1/rooms/.*/relations/{}/{}/{}$",
2664+
event_spec, rel_type, event_type
2665+
)));
2666+
}
2667+
_ => {
2668+
self.mock = self.mock.and(path_regex(format!(
2669+
r"^/_matrix/client/v1/rooms/.*/relations/{}",
2670+
event_spec,
2671+
)));
2672+
}
2673+
}
2674+
2675+
self.respond_with(ResponseTemplate::new(200).set_body_json(json!({
2676+
"chunk": response.chunk,
2677+
"next_batch": response.next_batch,
2678+
"prev_batch": response.prev_batch,
2679+
"recursion_depth": response.recursion_depth,
2680+
})))
2681+
}
2682+
}
2683+
2684+
/// A response to a [`RoomRelationsEndpoint`] query.
2685+
#[derive(Default)]
2686+
pub struct RoomRelationsResponseTemplate {
2687+
/// The set of timeline events returned by this query.
2688+
pub chunk: Vec<Raw<AnyTimelineEvent>>,
2689+
2690+
/// An opaque string representing a pagination token, which semantics depend
2691+
/// on the direction used in the request.
2692+
pub next_batch: Option<String>,
2693+
2694+
/// An opaque string representing a pagination token, which semantics depend
2695+
/// on the direction used in the request.
2696+
pub prev_batch: Option<String>,
2697+
2698+
/// If `recurse` was set on the request, the depth to which the server
2699+
/// recursed.
2700+
///
2701+
/// If `recurse` was not set, this field must be absent.
2702+
pub recursion_depth: Option<u32>,
2703+
}
2704+
2705+
impl RoomRelationsResponseTemplate {
2706+
/// Fill the events returned as part of this response.
2707+
pub fn events(mut self, chunk: Vec<impl Into<Raw<AnyTimelineEvent>>>) -> Self {
2708+
self.chunk = chunk.into_iter().map(Into::into).collect();
2709+
self
2710+
}
2711+
2712+
/// Fill the `next_batch` token returned as part of this response.
2713+
pub fn next_batch(mut self, token: impl Into<String>) -> Self {
2714+
self.next_batch = Some(token.into());
2715+
self
2716+
}
2717+
2718+
/// Fill the `prev_batch` token returned as part of this response.
2719+
pub fn prev_batch(mut self, token: impl Into<String>) -> Self {
2720+
self.prev_batch = Some(token.into());
2721+
self
2722+
}
2723+
2724+
/// Fill the recursion depth returned in this response.
2725+
pub fn recursion_depth(mut self, depth: u32) -> Self {
2726+
self.recursion_depth = Some(depth);
2727+
self
2728+
}
2729+
}

0 commit comments

Comments
 (0)