tests: allow bundled relations in EventBuidler

This commit is contained in:
Benjamin Bouvier
2024-10-02 16:00:35 +02:00
parent 45968b2a2b
commit 8a71ac622d
3 changed files with 113 additions and 124 deletions

View File

@@ -716,23 +716,24 @@ impl ReactionsByKeyBySender {
mod tests {
use assert_matches::assert_matches;
use assert_matches2::assert_let;
use matrix_sdk::test_utils::logged_in_client;
use matrix_sdk::test_utils::{events::EventFactory, logged_in_client};
use matrix_sdk_base::{
deserialized_responses::SyncTimelineEvent, latest_event::LatestEvent, sliding_sync::http,
MinimalStateEvent, OriginalMinimalStateEvent,
};
use matrix_sdk_test::{async_test, sync_timeline_event};
use ruma::{
event_id,
events::{
room::{
member::RoomMemberEventContent,
message::{MessageFormat, MessageType},
},
AnySyncTimelineEvent,
AnySyncTimelineEvent, BundledMessageLikeRelations,
},
room_id,
serde::Raw,
user_id, RoomId, UInt, UserId,
uint, user_id, MilliSecondsSinceUnixEpoch, RoomId, UInt, UserId,
};
use super::{EventTimelineItem, Profile};
@@ -773,48 +774,30 @@ mod tests {
// contains a bundled edit,
let room_id = room_id!("!q:x.uk");
let user_id = user_id!("@t:o.uk");
let event = sync_timeline_event!({
"event_id": "$eventid6",
"sender": user_id,
"origin_server_ts": 42,
"type": "m.room.message",
"room_id": room_id,
"content": {
"body": "**My M**",
"format": "org.matrix.custom.html",
"formatted_body": "<b>My M</b>" ,
"msgtype": "m.text"
},
"unsigned": {
"m.relations": {
"m.replace" : {
"sender" : user_id,
"content" : {
"format" : "org.matrix.custom.html",
"formatted_body" : " * <b>Updated!</b>",
"m.relates_to" : {
"event_id" : "$eventid6",
"rel_type" : "m.replace"
},
"m.new_content": {
"body" : "Updated!",
"formatted_body" : "<b>Updated!</b>",
"msgtype" : "m.text",
"format" : "org.matrix.custom.html"
},
"msgtype" : "m.text",
"body" : " * Updated!"
},
"origin_server_ts" : 43,
"room_id" : room_id,
"event_id" : "$edit-event-id",
"user_id" : user_id,
"type" : "m.room.message",
}
}
}
})
.into();
let f = EventFactory::new();
let original_event_id = event_id!("$original");
let mut relations = BundledMessageLikeRelations::new();
relations.replace = Some(Box::new(
f.text_html(" * Updated!", " * <b>Updated!</b>")
.edit(
original_event_id,
MessageType::text_html("Updated!", "<b>Updated!</b>").into(),
)
.event_id(event_id!("$edit"))
.sender(user_id)
.into_raw_sync(),
));
let event = f
.text_html("**My M**", "<b>My M</b>")
.sender(user_id)
.event_id(original_event_id)
.bundled_relations(relations)
.server_ts(MilliSecondsSinceUnixEpoch(uint!(42)))
.into_sync();
let client = logged_in_client(None).await;

View File

@@ -19,11 +19,13 @@ use eyeball_im::VectorDiff;
use matrix_sdk::deserialized_responses::{
AlgorithmInfo, EncryptionInfo, VerificationLevel, VerificationState,
};
use matrix_sdk_test::{async_test, sync_timeline_event, ALICE};
use matrix_sdk_test::{async_test, ALICE};
use ruma::{
event_id,
events::room::message::{MessageType, RedactedRoomMessageEventContent},
server_name, EventId,
events::{
room::message::{MessageType, RedactedRoomMessageEventContent},
BundledMessageLikeRelations,
},
};
use stream_assert::{assert_next_matches, assert_pending};
@@ -108,45 +110,36 @@ async fn test_aggregated_sanitized() {
let timeline = TestTimeline::new();
let mut stream = timeline.subscribe().await;
let original_event_id = EventId::new(server_name!("dummy.server"));
let ev = sync_timeline_event!({
"content": {
"formatted_body": "<strong>original</strong> message",
"format": "org.matrix.custom.html",
"body": "**original** message",
"msgtype": "m.text"
},
"event_id": &original_event_id,
"origin_server_ts": timeline.event_builder.next_server_ts(),
"sender": *ALICE,
"type": "m.room.message",
"unsigned": {
"m.relations": {
"m.replace": {
"content": {
"formatted_body": "* <edited/> <strong>better</strong> message",
"format": "org.matrix.custom.html",
"body": "* !!edited!! **better** message",
"m.new_content": {
"formatted_body": "<edited/> <strong>better</strong> message",
"format": "org.matrix.custom.html",
"body": "!!edited!! **better** message",
"msgtype": "m.text"
},
"m.relates_to": {
"event_id": original_event_id,
"rel_type": "m.replace"
},
"msgtype": "m.text"
},
"event_id": EventId::new(server_name!("dummy.server")),
"origin_server_ts": timeline.event_builder.next_server_ts(),
"sender": *ALICE,
"type": "m.room.message",
}
}
}
});
let original_event_id = event_id!("$original");
let edit_event_id = event_id!("$edit");
let f = &timeline.factory;
let mut relations = BundledMessageLikeRelations::new();
relations.replace = Some(Box::new(
f.text_html(
"* !!edited!! **better** message",
"* <edited/> <strong>better</strong> message",
)
.edit(
original_event_id,
MessageType::text_html(
"!!edited!! **better** message",
"<edited/> <strong>better</strong> message",
)
.into(),
)
.event_id(edit_event_id)
.sender(*ALICE)
.into_raw_sync(),
));
let ev = f
.text_html("**original** message", "<strong>original</strong> message")
.sender(*ALICE)
.event_id(original_event_id)
.bundled_relations(relations);
timeline.handle_live_event(ev).await;
let item = assert_next_matches!(stream, VectorDiff::PushBack { value } => value);
@@ -246,38 +239,21 @@ async fn test_relations_edit_overrides_pending_edit() {
assert_pending!(stream);
// Now we receive the original event, with a bundled relations group.
let ev = sync_timeline_event!({
"content": {
"body": "original",
"msgtype": "m.text"
},
"event_id": &original_event_id,
"origin_server_ts": timeline.event_builder.next_server_ts(),
"sender": *ALICE,
"type": "m.room.message",
"unsigned": {
"m.relations": {
"m.replace": {
"content": {
"body": "* edit 2",
"m.new_content": {
"body": "edit 2",
"msgtype": "m.text"
},
"m.relates_to": {
"event_id": original_event_id,
"rel_type": "m.replace"
},
"msgtype": "m.text"
},
"event_id": edit2_event_id,
"origin_server_ts": timeline.event_builder.next_server_ts(),
"sender": *ALICE,
"type": "m.room.message",
}
}
}
});
let mut relations = BundledMessageLikeRelations::new();
relations.replace = Some(Box::new(
f.text_msg("* edit 2")
.edit(original_event_id, MessageType::text_plain("edit 2").into())
.event_id(edit2_event_id)
.sender(*ALICE)
.into_raw_sync(),
));
let ev = f
.text_msg("original")
.sender(*ALICE)
.event_id(original_event_id)
.bundled_relations(relations);
timeline.handle_live_event(ev).await;
let item = assert_next_matches!(stream, VectorDiff::PushBack { value } => value);

View File

@@ -34,7 +34,7 @@ use ruma::{
message::{Relation, RoomMessageEventContent, RoomMessageEventContentWithoutRelation},
redaction::RoomRedactionEventContent,
},
AnySyncTimelineEvent, AnyTimelineEvent, EventContent,
AnySyncTimelineEvent, AnyTimelineEvent, BundledMessageLikeRelations, EventContent,
},
serde::Raw,
server_name, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId,
@@ -43,18 +43,19 @@ use ruma::{
use serde::Serialize;
use serde_json::json;
#[derive(Debug, Default, Serialize)]
#[derive(Debug, Default)]
struct Unsigned {
transaction_id: Option<OwnedTransactionId>,
relations: Option<BundledMessageLikeRelations<Raw<AnySyncTimelineEvent>>>,
}
#[derive(Debug)]
pub struct EventBuilder<E: EventContent> {
pub struct EventBuilder<C: EventContent> {
sender: Option<OwnedUserId>,
room: Option<OwnedRoomId>,
event_id: Option<OwnedEventId>,
redacts: Option<OwnedEventId>,
content: E,
content: C,
server_ts: MilliSecondsSinceUnixEpoch,
unsigned: Option<Unsigned>,
state_key: Option<String>,
@@ -90,6 +91,21 @@ where
self
}
/// Adds bundled relations to this event.
///
/// Ideally, we'd type-check that an event passed as a relation is the same
/// type as this one, but it's not trivial to do so because this builder
/// is only generic on the event's *content*, not the event type itself;
/// doing so would require many changes, and this is testing code after
/// all.
pub fn bundled_relations(
mut self,
relations: BundledMessageLikeRelations<Raw<AnySyncTimelineEvent>>,
) -> Self {
self.unsigned.get_or_insert_with(Default::default).relations = Some(relations);
self
}
pub fn state_key(mut self, state_key: impl Into<String>) -> Self {
self.state_key = Some(state_key.into());
self
@@ -122,9 +138,23 @@ where
if let Some(redacts) = self.redacts {
map.insert("redacts".to_owned(), json!(redacts));
}
if let Some(unsigned) = self.unsigned {
map.insert("unsigned".to_owned(), json!(unsigned));
let mut unsigned_json = json!({});
// We can't plain serialize `Unsigned`, otherwise this would result in some
// `null` fields when options are set to none, which Ruma rejects.
let unsigned_obj = unsigned_json.as_object_mut().unwrap();
if let Some(transaction_id) = unsigned.transaction_id {
unsigned_obj.insert("transaction_id".to_owned(), json!(transaction_id));
}
if let Some(relations) = unsigned.relations {
unsigned_obj.insert("m.relations".to_owned(), json!(relations));
}
map.insert("unsigned".to_owned(), unsigned_json);
}
if let Some(state_key) = self.state_key {
map.insert("state_key".to_owned(), json!(state_key));
}