testing: Add sync_timeline_event macro for more type safety in tests

This commit is contained in:
Jonas Platte
2023-09-21 11:43:54 +02:00
committed by Jonas Platte
parent 82f793ec0f
commit c8a4bc799b
10 changed files with 75 additions and 75 deletions

View File

@@ -15,7 +15,8 @@
use assert_matches::assert_matches;
use eyeball_im::VectorDiff;
use imbl::vector;
use matrix_sdk_test::async_test;
use matrix_sdk_base::deserialized_responses::SyncTimelineEvent;
use matrix_sdk_test::{async_test, sync_timeline_event};
use ruma::{
assign,
events::{
@@ -29,10 +30,9 @@ use ruma::{
FullStateEventContent,
},
};
use serde_json::json;
use stream_assert::assert_next_matches;
use super::{sync_timeline_event, TestTimeline, ALICE, BOB};
use super::{TestTimeline, ALICE, BOB};
use crate::timeline::{
event_item::AnyOtherFullStateEventContent, tests::CAROL, MembershipChange, TimelineDetails,
TimelineItemContent, TimelineItemKind, VirtualTimelineItem,
@@ -46,10 +46,10 @@ async fn initial_events() {
timeline
.inner
.add_initial_events(vector![
sync_timeline_event(
SyncTimelineEvent::new(
timeline.make_message_event(*ALICE, RoomMessageEventContent::text_plain("A")),
),
sync_timeline_event(
SyncTimelineEvent::new(
timeline.make_message_event(*BOB, RoomMessageEventContent::text_plain("B")),
),
])
@@ -69,7 +69,7 @@ async fn sticker() {
let mut stream = timeline.subscribe_events().await;
timeline
.handle_live_custom_event(json!({
.handle_live_custom_event(sync_timeline_event!({
"content": {
"body": "Happy sticker",
"info": {
@@ -195,7 +195,11 @@ async fn dedup_pagination() {
let event = timeline.make_message_event(*ALICE, RoomMessageEventContent::text_plain("o/"));
timeline.handle_live_custom_event(event.clone()).await;
timeline.handle_back_paginated_custom_event(event).await;
// This cast is not actually correct, sync events aren't valid
// back-paginated events, as they are missing `room_id`. However, the
// timeline doesn't care about that `room_id` and casts back to
// `Raw<AnySyncTimelineEvent>` before attempting to deserialize.
timeline.handle_back_paginated_custom_event(event.cast()).await;
let timeline_items = timeline.inner.items().await;
assert_eq!(timeline_items.len(), 2);
@@ -210,13 +214,13 @@ async fn dedup_pagination() {
async fn dedup_initial() {
let mut timeline = TestTimeline::new();
let event_a = sync_timeline_event(
let event_a = SyncTimelineEvent::new(
timeline.make_message_event(*ALICE, RoomMessageEventContent::text_plain("A")),
);
let event_b = sync_timeline_event(
let event_b = SyncTimelineEvent::new(
timeline.make_message_event(*BOB, RoomMessageEventContent::text_plain("B")),
);
let event_c = sync_timeline_event(
let event_c = SyncTimelineEvent::new(
timeline.make_message_event(*CAROL, RoomMessageEventContent::text_plain("C")),
);

View File

@@ -17,12 +17,11 @@ use std::{io, sync::Arc};
use assert_matches::assert_matches;
use eyeball_im::VectorDiff;
use matrix_sdk::Error;
use matrix_sdk_test::async_test;
use matrix_sdk_test::{async_test, sync_timeline_event};
use ruma::{
event_id,
events::{room::message::RoomMessageEventContent, AnyMessageLikeEventContent},
};
use serde_json::json;
use stream_assert::assert_next_matches;
use super::{TestTimeline, ALICE, BOB};
@@ -94,7 +93,7 @@ async fn remote_echo_full_trip() {
// Now, a sync has been run against the server, and an event with the same ID
// comes in.
timeline
.handle_live_custom_event(json!({
.handle_live_custom_event(sync_timeline_event!({
"content": {
"body": "echo",
"msgtype": "m.text",
@@ -140,7 +139,7 @@ async fn remote_echo_new_position() {
// When the remote echo comes in…
timeline
.handle_live_custom_event(json!({
.handle_live_custom_event(sync_timeline_event!({
"content": {
"body": "echo",
"msgtype": "m.text",
@@ -190,7 +189,7 @@ async fn day_divider_duplication() {
// … when the second remote event is re-received (day still the same)
let event_id = items[2].as_event().unwrap().event_id().unwrap();
timeline
.handle_live_custom_event(json!({
.handle_live_custom_event(sync_timeline_event!({
"content": {
"body": "B",
"msgtype": "m.text",

View File

@@ -14,7 +14,7 @@
use assert_matches::assert_matches;
use eyeball_im::VectorDiff;
use matrix_sdk_test::async_test;
use matrix_sdk_test::{async_test, sync_timeline_event};
use ruma::{
assign,
events::{
@@ -23,10 +23,8 @@ use ruma::{
self, MessageType, RedactedRoomMessageEventContent, RoomMessageEventContent,
},
},
serde::Raw,
server_name, EventId,
};
use serde_json::json;
use stream_assert::assert_next_matches;
use super::{TestTimeline, ALICE};
@@ -112,7 +110,7 @@ async fn aggregated_sanitized() {
let mut stream = timeline.subscribe().await;
let original_event_id = EventId::new(server_name!("dummy.server"));
let ev = json!({
let ev = sync_timeline_event!({
"content": {
"formatted_body": "<strong>original</strong> message",
"format": "org.matrix.custom.html",
@@ -150,7 +148,7 @@ async fn aggregated_sanitized() {
}
}
});
timeline.handle_live_event(Raw::new(&ev).unwrap().cast()).await;
timeline.handle_live_event(ev).await;
let _day_divider = assert_next_matches!(stream, VectorDiff::PushBack { value } => value);
let item = assert_next_matches!(stream, VectorDiff::PushBack { value } => value);

View File

@@ -16,7 +16,7 @@ use std::sync::Arc;
use assert_matches::assert_matches;
use eyeball_im::VectorDiff;
use matrix_sdk_test::async_test;
use matrix_sdk_test::{async_test, sync_timeline_event};
use ruma::{
assign,
events::{
@@ -32,7 +32,6 @@ use ruma::{
AnySyncTimelineEvent,
},
};
use serde_json::json;
use stream_assert::assert_next_matches;
use super::{TestTimeline, ALICE, BOB};
@@ -176,7 +175,7 @@ async fn hide_failed_to_parse() {
// m.room.message events must have a msgtype and body in content, so this
// event with an empty content object should fail to deserialize.
timeline
.handle_live_custom_event(json!({
.handle_live_custom_event(sync_timeline_event!({
"content": {},
"event_id": "$eeG0HA0FAZ37wP8kXlNkxx3I",
"origin_server_ts": 10,
@@ -188,7 +187,7 @@ async fn hide_failed_to_parse() {
// Similar to above, the m.room.member state event must also not have an
// empty content object.
timeline
.handle_live_custom_event(json!({
.handle_live_custom_event(sync_timeline_event!({
"content": {},
"event_id": "$d5G0HA0FAZ37wP8kXlNkxx3I",
"origin_server_ts": 2179,

View File

@@ -14,7 +14,7 @@
use assert_matches::assert_matches;
use eyeball_im::VectorDiff;
use matrix_sdk_test::async_test;
use matrix_sdk_test::{async_test, sync_timeline_event};
use ruma::{
assign,
events::{
@@ -24,7 +24,6 @@ use ruma::{
},
uint, MilliSecondsSinceUnixEpoch,
};
use serde_json::json;
use stream_assert::assert_next_matches;
use super::{TestTimeline, ALICE, BOB};
@@ -64,7 +63,7 @@ async fn invalid_event_content() {
// m.room.message events must have a msgtype and body in content, so this
// event with an empty content object should fail to deserialize.
timeline
.handle_live_custom_event(json!({
.handle_live_custom_event(sync_timeline_event!({
"content": {},
"event_id": "$eeG0HA0FAZ37wP8kXlNkxx3I",
"origin_server_ts": 10,
@@ -86,7 +85,7 @@ async fn invalid_event_content() {
// Similar to above, the m.room.member state event must also not have an
// empty content object.
timeline
.handle_live_custom_event(json!({
.handle_live_custom_event(sync_timeline_event!({
"content": {},
"event_id": "$d5G0HA0FAZ37wP8kXlNkxx3I",
"origin_server_ts": 2179,
@@ -119,7 +118,7 @@ async fn invalid_event() {
// This event is missing the sender field which the homeserver must add to
// all timeline events. Because the event is malformed, it will be ignored.
timeline
.handle_live_custom_event(json!({
.handle_live_custom_event(sync_timeline_event!({
"content": {
"body": "hello world",
"msgtype": "m.text"

View File

@@ -29,15 +29,16 @@ use futures_core::Stream;
use futures_util::{FutureExt, StreamExt};
use indexmap::IndexMap;
use matrix_sdk::deserialized_responses::{SyncTimelineEvent, TimelineEvent};
use matrix_sdk_test::sync_timeline_event;
use once_cell::sync::Lazy;
use ruma::{
events::{
receipt::{Receipt, ReceiptEventContent, ReceiptThread, ReceiptType},
relation::Annotation,
room::redaction::RoomRedactionEventContent,
AnyMessageLikeEventContent, AnySyncTimelineEvent, EmptyStateKey, MessageLikeEventContent,
RedactedMessageLikeEventContent, RedactedStateEventContent, StateEventContent,
StaticStateEventContent,
AnyMessageLikeEventContent, AnySyncTimelineEvent, AnyTimelineEvent, EmptyStateKey,
MessageLikeEventContent, RedactedMessageLikeEventContent, RedactedStateEventContent,
StateEventContent, StaticStateEventContent,
},
int,
power_levels::NotificationPowerLevels,
@@ -75,11 +76,6 @@ static ALICE: Lazy<&UserId> = Lazy::new(|| user_id!("@alice:server.name"));
static BOB: Lazy<&UserId> = Lazy::new(|| user_id!("@bob:other.server"));
static CAROL: Lazy<&UserId> = Lazy::new(|| user_id!("@carol:other.server"));
fn sync_timeline_event(event: JsonValue) -> SyncTimelineEvent {
let event = serde_json::from_value(event).unwrap();
SyncTimelineEvent { event, encryption_info: None, push_actions: Vec::default() }
}
struct TestTimeline {
inner: TimelineInner<TestRoomDataProvider>,
next_ts: AtomicU64,
@@ -133,7 +129,7 @@ impl TestTimeline {
C: StaticStateEventContent<StateKey = EmptyStateKey>,
{
let ev = self.make_state_event(sender, "", content, prev_content);
self.handle_live_event(Raw::new(&ev).unwrap().cast()).await;
self.handle_live_event(ev).await;
}
async fn handle_live_state_event_with_state_key<C>(
@@ -169,13 +165,12 @@ impl TestTimeline {
self.handle_live_event(Raw::new(&ev).unwrap().cast()).await;
}
async fn handle_live_custom_event(&self, event: JsonValue) {
let raw = Raw::new(&event).unwrap().cast();
self.handle_live_event(raw).await;
async fn handle_live_custom_event(&self, event: Raw<AnySyncTimelineEvent>) {
self.handle_live_event(event).await;
}
async fn handle_live_redaction(&self, sender: &UserId, redacts: &EventId) {
let ev = json!({
let ev = sync_timeline_event!({
"type": "m.room.redaction",
"content": {},
"redacts": redacts,
@@ -183,13 +178,12 @@ impl TestTimeline {
"sender": sender,
"origin_server_ts": self.next_server_ts(),
});
let raw = Raw::new(&ev).unwrap().cast();
self.handle_live_event(raw).await;
self.handle_live_event(ev).await;
}
async fn handle_live_reaction(&self, sender: &UserId, annotation: &Annotation) -> OwnedEventId {
let event_id = EventId::new(server_name!("dummy.server"));
let ev = json!({
let ev = sync_timeline_event!({
"type": "m.reaction",
"content": {
"m.relates_to": {
@@ -202,8 +196,7 @@ impl TestTimeline {
"sender": sender,
"origin_server_ts": self.next_server_ts(),
});
let raw = Raw::new(&ev).unwrap().cast();
self.handle_live_event(raw).await;
self.handle_live_event(ev).await;
event_id
}
@@ -228,8 +221,8 @@ impl TestTimeline {
txn_id
}
async fn handle_back_paginated_custom_event(&self, event: JsonValue) {
let timeline_event = TimelineEvent::new(Raw::new(&event).unwrap().cast());
async fn handle_back_paginated_custom_event(&self, event: Raw<AnyTimelineEvent>) {
let timeline_event = TimelineEvent::new(event.cast());
self.inner.handle_back_paginated_events(vec![timeline_event]).await;
}
@@ -267,7 +260,7 @@ impl TestTimeline {
&self,
sender: &UserId,
content: C,
) -> JsonValue {
) -> Raw<AnySyncTimelineEvent> {
self.make_message_event_with_id(sender, content, EventId::new(server_name!("dummy.server")))
}
@@ -276,8 +269,8 @@ impl TestTimeline {
sender: &UserId,
content: C,
event_id: OwnedEventId,
) -> JsonValue {
json!({
) -> Raw<AnySyncTimelineEvent> {
sync_timeline_event!({
"type": content.event_type(),
"content": content,
"event_id": event_id,
@@ -290,8 +283,8 @@ impl TestTimeline {
&self,
sender: &UserId,
content: C,
) -> JsonValue {
json!({
) -> Raw<AnySyncTimelineEvent> {
sync_timeline_event!({
"type": content.event_type(),
"content": content,
"event_id": EventId::new(server_name!("dummy.server")),
@@ -307,14 +300,14 @@ impl TestTimeline {
state_key: &str,
content: C,
prev_content: Option<C>,
) -> JsonValue {
) -> Raw<AnySyncTimelineEvent> {
let unsigned = if let Some(prev_content) = prev_content {
json!({ "prev_content": prev_content })
} else {
json!({})
};
json!({
sync_timeline_event!({
"type": content.event_type(),
"state_key": state_key,
"content": content,
@@ -330,8 +323,8 @@ impl TestTimeline {
sender: &UserId,
state_key: &str,
content: C,
) -> JsonValue {
json!({
) -> Raw<AnySyncTimelineEvent> {
sync_timeline_event!({
"type": content.event_type(),
"state_key": state_key,
"content": content,
@@ -359,8 +352,8 @@ impl TestTimeline {
sender: &UserId,
annotation: &Annotation,
timestamp: MilliSecondsSinceUnixEpoch,
) -> JsonValue {
json!({
) -> Raw<AnySyncTimelineEvent> {
sync_timeline_event!({
"event_id": EventId::new(server_name!("dummy.server")),
"content": {
"m.relates_to": {

View File

@@ -11,7 +11,6 @@ use ruma::{
},
AnyMessageLikeEventContent,
},
serde::Raw,
server_name, EventId, OwnedEventId, UserId,
};
@@ -217,8 +216,7 @@ impl TestTimeline {
NewUnstablePollStartEventContent::new(content).into(),
);
let event = self.make_message_event_with_id(sender, event_content, event_id.to_owned());
let raw = Raw::new(&event).unwrap().cast();
self.handle_live_event(raw).await;
self.handle_live_event(event).await;
}
async fn send_poll_response(&self, sender: &UserId, answers: Vec<&str>, poll_id: &EventId) {

View File

@@ -18,6 +18,7 @@ use assert_matches::assert_matches;
use eyeball_im::VectorDiff;
use futures_core::Stream;
use imbl::vector;
use matrix_sdk_base::deserialized_responses::SyncTimelineEvent;
use matrix_sdk_test::async_test;
use ruma::{
events::{relation::Annotation, room::message::RoomMessageEventContent},
@@ -29,10 +30,7 @@ use crate::timeline::{
event_item::EventItemIdentifier,
inner::ReactionAction,
reactions::ReactionToggleResult,
tests::{
assert_event_is_updated, assert_no_more_updates, sync_timeline_event, TestTimeline, ALICE,
BOB,
},
tests::{assert_event_is_updated, assert_no_more_updates, TestTimeline, ALICE, BOB},
TimelineItem,
};
@@ -249,12 +247,12 @@ async fn initial_reaction_timestamp_is_stored() {
timeline
.inner
.add_initial_events(vector![
sync_timeline_event(timeline.make_reaction(
SyncTimelineEvent::new(timeline.make_reaction(
*ALICE,
&Annotation::new(message_event_id.clone(), REACTION_KEY.to_owned()),
reaction_timestamp
)),
sync_timeline_event(timeline.make_message_event_with_id(
SyncTimelineEvent::new(timeline.make_message_event_with_id(
*ALICE,
RoomMessageEventContent::text_plain("A"),
message_event_id

View File

@@ -15,7 +15,8 @@
use assert_matches::assert_matches;
use eyeball_im::VectorDiff;
use imbl::vector;
use matrix_sdk_test::async_test;
use matrix_sdk_base::deserialized_responses::SyncTimelineEvent;
use matrix_sdk_test::{async_test, sync_timeline_event};
use ruma::{
events::{
reaction::{ReactionEventContent, RedactedReactionEventContent},
@@ -31,10 +32,9 @@ use ruma::{
},
owned_room_id,
};
use serde_json::json;
use stream_assert::assert_next_matches;
use super::{sync_timeline_event, TestTimeline, ALICE, BOB};
use super::{TestTimeline, ALICE, BOB};
use crate::timeline::{AnyOtherFullStateEventContent, TimelineDetails, TimelineItemContent};
#[async_test]
@@ -146,7 +146,7 @@ async fn reaction_redaction_timeline_filter() {
// Initialise a timeline with a redacted reaction.
timeline
.inner
.add_initial_events(vector![sync_timeline_event(
.add_initial_events(vector![SyncTimelineEvent::new(
timeline.make_redacted_message_event(*ALICE, RedactedReactionEventContent::new())
)])
.await;
@@ -209,7 +209,7 @@ async fn receive_unredacted() {
// send new events with the same event ID as the previous ones
timeline
.handle_live_custom_event(json!({
.handle_live_custom_event(sync_timeline_event!({
"content": {
"body": "unredacted #1",
"msgtype": "m.text",
@@ -221,7 +221,7 @@ async fn receive_unredacted() {
}))
.await;
timeline
.handle_live_custom_event(json!({
.handle_live_custom_event(sync_timeline_event!({
"content": {
"body": "unredacted #2",
"msgtype": "m.text",

View File

@@ -3,6 +3,18 @@ pub use matrix_sdk_test_macros::async_test;
use ruma::api::{client::sync::sync_events::v3::Response as SyncResponse, IncomingResponse};
use serde_json::Value as JsonValue;
/// Create a `Raw<AnySyncTimelineEvent>` from arbitrary JSON.
///
/// Forwards all arguments to [`serde_json::json`].
#[macro_export]
macro_rules! sync_timeline_event {
($( $tt:tt )*) => {
::ruma::serde::Raw::new(&::serde_json::json!( $($tt)* ))
.unwrap()
.cast::<::ruma::events::AnySyncTimelineEvent>()
}
}
pub mod notification_settings;
mod sync_builder;
pub mod test_json;