tests: get rid of EventBuilder::make_redaction_event and TestTimeline::handle_live_reaction

The `EventFactory` is improved to support creating those events too,
reducing the number of custom events creators everywhere.
This commit is contained in:
Benjamin Bouvier
2024-07-09 19:26:02 +02:00
parent f7504b4ff2
commit a0a076a895
5 changed files with 95 additions and 86 deletions
@@ -17,6 +17,7 @@ use std::sync::Arc;
use assert_matches::assert_matches;
use assert_matches2::assert_let;
use eyeball_im::VectorDiff;
use matrix_sdk::test_utils::events::EventFactory;
use matrix_sdk_test::{async_test, sync_timeline_event, ALICE, BOB};
use ruma::{
assign,
@@ -47,10 +48,11 @@ async fn test_default_filter() {
let timeline = TestTimeline::new();
let mut stream = timeline.subscribe().await;
let f = EventFactory::new();
// Test edits work.
timeline
.handle_live_message_event(&ALICE, RoomMessageEventContent::text_plain("The first message"))
.await;
timeline.handle_live_event(f.text_msg("The first message").sender(&ALICE)).await;
let item = assert_next_matches!(stream, VectorDiff::PushBack { value } => value);
let _day_divider = assert_next_matches!(stream, VectorDiff::PushFront { value } => value);
let first_event_id = item.as_event().unwrap().event_id().unwrap();
@@ -72,31 +74,24 @@ async fn test_default_filter() {
// TODO: After adding raw timeline items, check for one here.
// Test redactions work.
timeline
.handle_live_message_event(
&ALICE,
RoomMessageEventContent::text_plain("The second message"),
)
.await;
timeline.handle_live_event(f.text_msg("The second message").sender(&ALICE)).await;
let item = assert_next_matches!(stream, VectorDiff::PushBack { value } => value);
let second_event_id = item.as_event().unwrap().event_id().unwrap();
timeline.handle_live_redaction(&BOB, second_event_id).await;
timeline.handle_live_event(f.redaction(second_event_id).sender(&BOB)).await;
let item = assert_next_matches!(stream, VectorDiff::Set { index: 2, value } => value);
assert_matches!(item.as_event().unwrap().content(), TimelineItemContent::RedactedMessage);
// TODO: After adding raw timeline items, check for one here.
// Test reactions work.
timeline
.handle_live_message_event(&ALICE, RoomMessageEventContent::text_plain("The third message"))
.await;
timeline.handle_live_event(f.text_msg("The third message").sender(&ALICE)).await;
let item = assert_next_matches!(stream, VectorDiff::PushBack { value } => value);
let third_event_id = item.as_event().unwrap().event_id().unwrap();
let rel = Annotation::new(third_event_id.to_owned(), "+1".to_owned());
timeline.handle_live_message_event(&BOB, ReactionEventContent::new(rel)).await;
timeline.handle_live_redaction(&BOB, second_event_id).await;
timeline.handle_live_event(f.redaction(second_event_id).sender(&BOB)).await;
let item = assert_next_matches!(stream, VectorDiff::Set { index: 3, value } => value);
assert_eq!(item.as_event().unwrap().reactions().len(), 1);
+4 -10
View File
@@ -37,9 +37,8 @@ use ruma::{
events::{
receipt::{Receipt, ReceiptThread, ReceiptType},
relation::Annotation,
AnyMessageLikeEventContent, AnySyncTimelineEvent, AnyTimelineEvent, EmptyStateKey,
MessageLikeEventContent, RedactedMessageLikeEventContent, RedactedStateEventContent,
StaticStateEventContent,
AnyMessageLikeEventContent, AnyTimelineEvent, EmptyStateKey, MessageLikeEventContent,
RedactedMessageLikeEventContent, RedactedStateEventContent, StaticStateEventContent,
},
int,
power_levels::NotificationPowerLevels,
@@ -212,11 +211,6 @@ impl TestTimeline {
self.handle_live_event(Raw::new(&ev).unwrap().cast()).await;
}
async fn handle_live_redaction(&self, sender: &UserId, redacts: &EventId) {
let ev = self.event_builder.make_redaction_event(sender, redacts);
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 = self.event_builder.make_reaction_event(sender, &event_id, annotation);
@@ -224,8 +218,8 @@ impl TestTimeline {
event_id
}
async fn handle_live_event(&self, event: Raw<AnySyncTimelineEvent>) {
let event = SyncTimelineEvent::new(event);
async fn handle_live_event(&self, event: impl Into<SyncTimelineEvent>) {
let event = event.into();
self.inner.add_events_at(vec![event], TimelineEnd::Back, RemoteEventOrigin::Sync).await;
}
@@ -15,12 +15,12 @@
use assert_matches::assert_matches;
use assert_matches2::assert_let;
use eyeball_im::VectorDiff;
use matrix_sdk::test_utils::events::EventFactory;
use matrix_sdk_base::deserialized_responses::SyncTimelineEvent;
use matrix_sdk_test::{async_test, sync_timeline_event, ALICE, BOB};
use matrix_sdk_test::{async_test, ALICE, BOB};
use ruma::{
events::{
reaction::{ReactionEventContent, RedactedReactionEventContent},
relation::Annotation,
reaction::RedactedReactionEventContent,
room::{
message::{
AddMentions, ForwardThread, OriginalSyncRoomMessageEvent,
@@ -45,6 +45,8 @@ async fn test_redact_state_event() {
let timeline = TestTimeline::new();
let mut stream = timeline.subscribe_events().await;
let f = EventFactory::new();
timeline
.handle_live_state_event(
&ALICE,
@@ -60,7 +62,7 @@ async fn test_redact_state_event() {
AnyOtherFullStateEventContent::RoomName(FullStateEventContent::Original { .. })
);
timeline.handle_live_redaction(&ALICE, item.event_id().unwrap()).await;
timeline.handle_live_event(f.redaction(item.event_id().unwrap()).sender(&ALICE)).await;
let item = assert_next_matches!(stream, VectorDiff::Set { index: 0, value } => value);
assert_let!(TimelineItemContent::OtherState(state) = item.content());
@@ -75,9 +77,9 @@ async fn test_redact_replied_to_event() {
let timeline = TestTimeline::new();
let mut stream = timeline.subscribe_events().await;
timeline
.handle_live_message_event(&ALICE, RoomMessageEventContent::text_plain("Hello, world!"))
.await;
let f = EventFactory::new();
timeline.handle_live_event(f.text_msg("Hello, world!").sender(&ALICE)).await;
let first_item = assert_next_matches!(stream, VectorDiff::PushBack { value } => value);
assert_matches!(first_item.content(), TimelineItemContent::Message(_));
@@ -101,7 +103,7 @@ async fn test_redact_replied_to_event() {
assert_let!(TimelineDetails::Ready(replied_to_event) = &in_reply_to.event);
assert_matches!(replied_to_event.content(), TimelineItemContent::Message(_));
timeline.handle_live_redaction(&ALICE, first_item.event_id().unwrap()).await;
timeline.handle_live_event(f.redaction(first_item.event_id().unwrap()).sender(&ALICE)).await;
let first_item_again =
assert_next_matches!(stream, VectorDiff::Set { index: 0, value } => value);
@@ -121,14 +123,15 @@ async fn test_reaction_redaction() {
let timeline = TestTimeline::new();
let mut stream = timeline.subscribe_events().await;
timeline.handle_live_message_event(&ALICE, RoomMessageEventContent::text_plain("hi!")).await;
let f = EventFactory::new();
timeline.handle_live_event(f.text_msg("hi!").sender(&ALICE)).await;
let item = assert_next_matches!(stream, VectorDiff::PushBack { value } => value);
assert_eq!(item.reactions().len(), 0);
let msg_event_id = item.event_id().unwrap();
let rel = Annotation::new(msg_event_id.to_owned(), "+1".to_owned());
timeline.handle_live_message_event(&BOB, ReactionEventContent::new(rel)).await;
timeline.handle_live_event(f.reaction(msg_event_id, "+1".to_owned()).sender(&BOB)).await;
let item = assert_next_matches!(stream, VectorDiff::Set { index: 0, value } => value);
assert_eq!(item.reactions().len(), 1);
@@ -136,7 +139,7 @@ async fn test_reaction_redaction() {
let reaction_event_id = item.event_id().unwrap();
timeline.handle_live_redaction(&BOB, reaction_event_id).await;
timeline.handle_live_event(f.redaction(reaction_event_id).sender(&BOB)).await;
let item = assert_next_matches!(stream, VectorDiff::Set { index: 0, value } => value);
assert_eq!(item.reactions().len(), 0);
}
@@ -146,6 +149,8 @@ async fn test_reaction_redaction_timeline_filter() {
let timeline = TestTimeline::new();
let mut stream = timeline.subscribe_events().await;
let f = EventFactory::new();
// Initialise a timeline with a redacted reaction.
timeline
.inner
@@ -167,20 +172,21 @@ async fn test_reaction_redaction_timeline_filter() {
assert_eq!(timeline.inner.items().await.len(), 0);
// Adding a room message
timeline.handle_live_message_event(&ALICE, RoomMessageEventContent::text_plain("hi!")).await;
timeline.handle_live_event(f.text_msg("hi!").sender(&ALICE)).await;
let item = assert_next_matches!(stream, VectorDiff::PushBack { value } => value);
// Creates a day divider and the message.
assert_eq!(timeline.inner.items().await.len(), 2);
// Reaction is attached to the message and doesn't add a timeline item.
let rel = Annotation::new(item.event_id().unwrap().to_owned(), "+1".to_owned());
timeline.handle_live_message_event(&BOB, ReactionEventContent::new(rel)).await;
timeline
.handle_live_event(f.reaction(item.event_id().unwrap(), "+1".to_owned()).sender(&BOB))
.await;
let item = assert_next_matches!(stream, VectorDiff::Set { index: 0, value } => value);
let reaction_event_id = item.event_id().unwrap();
assert_eq!(timeline.inner.items().await.len(), 2);
// Redacting the reaction doesn't add a timeline item.
timeline.handle_live_redaction(&BOB, reaction_event_id).await;
timeline.handle_live_event(f.redaction(reaction_event_id).sender(&BOB)).await;
let item = assert_next_matches!(stream, VectorDiff::Set { index: 0, value } => value);
assert_eq!(item.reactions().len(), 0);
assert_eq!(timeline.inner.items().await.len(), 2);
@@ -190,13 +196,10 @@ async fn test_reaction_redaction_timeline_filter() {
async fn test_receive_unredacted() {
let timeline = TestTimeline::new();
let f = EventFactory::new();
// send two events, second one redacted
timeline
.handle_live_message_event(
&ALICE,
RoomMessageEventContent::text_plain("about to be redacted"),
)
.await;
timeline.handle_live_event(f.text_msg("about to be redacted").sender(&ALICE)).await;
timeline
.handle_live_redacted_message_event(&ALICE, RedactedRoomMessageEventContent::new())
.await;
@@ -205,7 +208,7 @@ async fn test_receive_unredacted() {
let items = timeline.inner.items().await;
assert!(items[0].is_day_divider());
let fst = items[1].as_event().unwrap();
timeline.handle_live_redaction(&ALICE, fst.event_id().unwrap()).await;
timeline.handle_live_event(f.redaction(fst.event_id().unwrap()).sender(&ALICE)).await;
let items = timeline.inner.items().await;
assert_eq!(items.len(), 3);
@@ -218,28 +221,21 @@ async fn test_receive_unredacted() {
// send new events with the same event ID as the previous ones
timeline
.handle_live_event(sync_timeline_event!({
"content": {
"body": "unredacted #1",
"msgtype": "m.text",
},
"sender": &*ALICE,
"event_id": fst.event_id().unwrap(),
"origin_server_ts": fst.timestamp(),
"type": "m.room.message",
}))
.handle_live_event(
f.text_msg("unredacted #1")
.sender(*ALICE)
.event_id(fst.event_id().unwrap())
.server_ts(fst.timestamp()),
)
.await;
timeline
.handle_live_event(sync_timeline_event!({
"content": {
"body": "unredacted #2",
"msgtype": "m.text",
},
"sender": &*ALICE,
"event_id": snd.event_id().unwrap(),
"origin_server_ts": snd.timestamp(),
"type": "m.room.message",
}))
.handle_live_event(
f.text_msg("unredacted #2")
.sender(*ALICE)
.event_id(snd.event_id().unwrap())
.server_ts(snd.timestamp()),
)
.await;
// make sure we still have two redacted events
+43 -4
View File
@@ -20,8 +20,12 @@ use matrix_sdk_base::deserialized_responses::{SyncTimelineEvent, TimelineEvent};
use matrix_sdk_test::{sync_timeline_event, timeline_event};
use ruma::{
events::{
relation::InReplyTo,
room::message::{Relation, RoomMessageEventContent},
reaction::ReactionEventContent,
relation::{Annotation, InReplyTo},
room::{
message::{Relation, RoomMessageEventContent},
redaction::RoomRedactionEventContent,
},
AnySyncTimelineEvent, AnyTimelineEvent, EventContent,
},
serde::Raw,
@@ -35,6 +39,7 @@ pub struct EventBuilder<E: EventContent> {
sender: Option<OwnedUserId>,
room: Option<OwnedRoomId>,
event_id: Option<OwnedEventId>,
redacts: Option<OwnedEventId>,
content: E,
server_ts: MilliSecondsSinceUnixEpoch,
}
@@ -58,6 +63,11 @@ where
self
}
pub fn server_ts(mut self, ts: MilliSecondsSinceUnixEpoch) -> Self {
self.server_ts = ts;
self
}
pub fn into_raw_timeline(self) -> Raw<AnyTimelineEvent> {
let room_id = self.room.expect("we should have a room id at this point");
let event_id =
@@ -69,7 +79,8 @@ where
"event_id": event_id,
"sender": self.sender.expect("we should have a sender user id at this point"),
"room_id": room_id,
"origin_server_ts": self.server_ts
"origin_server_ts": self.server_ts,
"redacts": self.redacts,
})
}
@@ -88,7 +99,8 @@ where
"content": self.content,
"event_id": event_id,
"sender": self.sender.expect("we should have a sender user id at this point"),
"origin_server_ts": self.server_ts
"origin_server_ts": self.server_ts,
"redacts": self.redacts,
})
}
@@ -114,6 +126,15 @@ where
}
}
impl<E: EventContent> From<EventBuilder<E>> for SyncTimelineEvent
where
E::EventType: Serialize,
{
fn from(val: EventBuilder<E>) -> Self {
val.into_sync()
}
}
#[derive(Debug, Default)]
pub struct EventFactory {
next_ts: AtomicU64,
@@ -145,12 +166,14 @@ impl EventFactory {
)
}
/// Create an event from any event content.
pub fn event<E: EventContent>(&self, content: E) -> EventBuilder<E> {
EventBuilder {
sender: self.sender.clone(),
room: self.room.clone(),
server_ts: self.next_server_ts(),
event_id: None,
redacts: None,
content,
}
}
@@ -165,6 +188,22 @@ impl EventFactory {
self.event(RoomMessageEventContent::notice_plain(content))
}
/// Add a reaction to an event.
pub fn reaction(
&self,
event_id: &EventId,
annotation: String,
) -> EventBuilder<ReactionEventContent> {
self.event(ReactionEventContent::new(Annotation::new(event_id.to_owned(), annotation)))
}
/// Create a redaction for the given event id.
pub fn redaction(&self, event_id: &EventId) -> EventBuilder<RoomRedactionEventContent> {
let mut builder = self.event(RoomRedactionEventContent::new_v11(event_id.to_owned()));
builder.redacts = Some(event_id.to_owned());
builder
}
/// Set the next server timestamp.
///
/// Timestamps will continue to increase by 1 (millisecond) from that value.
@@ -235,21 +235,6 @@ impl EventBuilder {
ev_content
}
pub fn make_redaction_event(
&self,
sender: &UserId,
redacts: &EventId,
) -> Raw<AnySyncTimelineEvent> {
sync_timeline_event!({
"type": "m.room.redaction",
"content": {},
"redacts": redacts,
"event_id": EventId::new(server_name!("dummy.server")),
"sender": sender,
"origin_server_ts": self.next_server_ts(),
})
}
pub fn make_reaction_event(
&self,
sender: &UserId,