matrix_sdk_test/
lib.rs

1use std::fmt;
2
3use http::Response;
4pub use matrix_sdk_test_macros::async_test;
5use once_cell::sync::Lazy;
6use ruma::{
7    RoomId, UserId,
8    api::{IncomingResponse, OutgoingResponse},
9    room_id, user_id,
10};
11
12/// Create a `Raw<AnyMessageLikeEventContent>` from arbitrary JSON.
13///
14/// Forwards all arguments to [`serde_json::json`].
15#[macro_export]
16macro_rules! message_like_event_content {
17    ($( $tt:tt )*) => {
18        ::ruma::serde::Raw::new(&::serde_json::json!( $($tt)* ))
19            .unwrap()
20            .cast_unchecked::<::ruma::events::AnyMessageLikeEventContent>()
21    }
22}
23
24/// Create a `Raw<AnyTimelineEvent>` from arbitrary JSON.
25///
26/// Forwards all arguments to [`serde_json::json`].
27#[macro_export]
28macro_rules! timeline_event {
29    ($( $tt:tt )*) => {
30        ::ruma::serde::Raw::new(&::serde_json::json!( $($tt)* ))
31            .unwrap()
32            .cast_unchecked::<::ruma::events::AnyTimelineEvent>()
33    }
34}
35
36/// Create a `Raw<AnySyncTimelineEvent>` from arbitrary JSON.
37///
38/// Forwards all arguments to [`serde_json::json`].
39#[macro_export]
40macro_rules! sync_timeline_event {
41    ($( $tt:tt )*) => {
42        ::ruma::serde::Raw::new(&::serde_json::json!( $($tt)* ))
43            .unwrap()
44            .cast_unchecked::<::ruma::events::AnySyncTimelineEvent>()
45    }
46}
47
48/// Create a `Raw<AnySyncStateEvent>` from arbitrary JSON.
49///
50/// Forwards all arguments to [`serde_json::json`].
51#[macro_export]
52macro_rules! sync_state_event {
53    ($( $tt:tt )*) => {
54        ::ruma::serde::Raw::new(&::serde_json::json!( $($tt)* ))
55            .unwrap()
56            .cast_unchecked::<::ruma::events::AnySyncStateEvent>()
57    }
58}
59
60/// Create a `Raw<AnyStrippedStateEvent>` from arbitrary JSON.
61///
62/// Forwards all arguments to [`serde_json::json`].
63#[macro_export]
64macro_rules! stripped_state_event {
65    ($( $tt:tt )*) => {
66        ::ruma::serde::Raw::new(&::serde_json::json!( $($tt)* ))
67            .unwrap()
68            .cast_unchecked::<::ruma::events::AnyStrippedStateEvent>()
69    }
70}
71
72#[cfg(not(target_family = "wasm"))]
73pub mod mocks;
74
75pub mod event_factory;
76pub mod notification_settings;
77mod sync_builder;
78pub mod test_json;
79
80pub use self::sync_builder::{
81    InvitedRoomBuilder, JoinedRoomBuilder, KnockedRoomBuilder, LeftRoomBuilder, PresenceTestEvent,
82    RoomAccountDataTestEvent, StateTestEvent, StrippedStateTestEvent, SyncResponseBuilder,
83    bulk_room_members,
84};
85
86pub static ALICE: Lazy<&UserId> = Lazy::new(|| user_id!("@alice:server.name"));
87pub static BOB: Lazy<&UserId> = Lazy::new(|| user_id!("@bob:other.server"));
88pub static CAROL: Lazy<&UserId> = Lazy::new(|| user_id!("@carol:other.server"));
89
90/// The default room ID for tests.
91pub static DEFAULT_TEST_ROOM_ID: Lazy<&RoomId> =
92    Lazy::new(|| room_id!("!SVkFJHzfwvuaIEawgC:localhost"));
93
94/// Build a typed Ruma [`IncomingResponse`] object from a json body.
95pub fn ruma_response_from_json<ResponseType: IncomingResponse>(
96    json: &serde_json::Value,
97) -> ResponseType {
98    let json_bytes = serde_json::to_vec(json).expect("JSON-serialization of response value failed");
99    let http_response =
100        Response::builder().status(200).body(json_bytes).expect("Failed to build HTTP response");
101    ResponseType::try_from_http_response(http_response).expect("Can't parse the response json")
102}
103
104/// Serialise a typed Ruma [`OutgoingResponse`] object to JSON.
105pub fn ruma_response_to_json<ResponseType: OutgoingResponse>(
106    response: ResponseType,
107) -> serde_json::Value {
108    let http_response: Response<Vec<u8>> =
109        response.try_into_http_response().expect("Failed to build HTTP response");
110    let json_bytes = http_response.into_body();
111    serde_json::from_slice(&json_bytes).expect("Can't parse the response JSON")
112}
113
114#[derive(Debug)] // required to be able to return TestResult from #[test] fns
115pub enum TestError {}
116
117// If this was just `T: Debug`, it would conflict with
118// the `impl From<T> for T` in `std`.
119//
120// Adding a dummy `Display` bound works around this.
121impl<T: fmt::Display + fmt::Debug> From<T> for TestError {
122    #[track_caller]
123    fn from(value: T) -> Self {
124        panic!("error: {value:?}")
125    }
126}
127
128pub type TestResult = Result<(), TestError>;