To prevent users from constructing them. We also change some methods to access the custom data to work with all variants, otherwise they might break when new variants are added.
402 lines
13 KiB
Rust
402 lines
13 KiB
Rust
use assert_matches2::{assert_let, assert_matches};
|
|
use assign::assign;
|
|
#[cfg(feature = "unstable-msc3381")]
|
|
use ruma_common::event_id;
|
|
use ruma_common::{canonical_json::assert_to_canonical_json_eq, owned_event_id, serde::Raw};
|
|
#[cfg(feature = "unstable-msc3381")]
|
|
use ruma_events::poll::{
|
|
start::{PollAnswer, PollContentBlock, PollStartEventContent},
|
|
unstable_start::{
|
|
NewUnstablePollStartEventContent, UnstablePollAnswer, UnstablePollStartContentBlock,
|
|
UnstablePollStartEventContent,
|
|
},
|
|
};
|
|
#[cfg(feature = "unstable-msc3381")]
|
|
use ruma_events::{
|
|
AnyMessageLikeEventContent,
|
|
message::TextContentBlock,
|
|
room::{encrypted, message::RelationWithoutReplacement},
|
|
};
|
|
use ruma_events::{
|
|
relation::{Replacement, Reply, Thread},
|
|
room::message::{MessageType, Relation, RoomMessageEventContent},
|
|
};
|
|
use serde_json::{Value as JsonValue, from_value as from_json_value, json};
|
|
|
|
#[test]
|
|
fn reply_deserialize() {
|
|
let json = json!({
|
|
"msgtype": "m.text",
|
|
"body": "<text msg>",
|
|
"m.relates_to": {
|
|
"m.in_reply_to": {
|
|
"event_id": "$1598361704261elfgc:localhost",
|
|
},
|
|
},
|
|
});
|
|
|
|
assert_matches!(
|
|
from_json_value::<RoomMessageEventContent>(json),
|
|
Ok(RoomMessageEventContent {
|
|
msgtype: MessageType::Text(_),
|
|
relates_to: Some(Relation::Reply(reply)),
|
|
..
|
|
})
|
|
);
|
|
assert_eq!(reply.in_reply_to.event_id, "$1598361704261elfgc:localhost");
|
|
}
|
|
|
|
#[test]
|
|
fn reply_serialize() {
|
|
let content = assign!(RoomMessageEventContent::text_plain("This is a reply"), {
|
|
relates_to: Some(Relation::Reply(Reply::with_event_id(owned_event_id!("$1598361704261elfgc")) )),
|
|
});
|
|
|
|
assert_to_canonical_json_eq!(
|
|
content,
|
|
json!({
|
|
"msgtype": "m.text",
|
|
"body": "This is a reply",
|
|
"m.relates_to": {
|
|
"m.in_reply_to": {
|
|
"event_id": "$1598361704261elfgc",
|
|
},
|
|
},
|
|
})
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn reply_serialization_roundtrip() {
|
|
let body = "This is a reply";
|
|
let mut content = RoomMessageEventContent::text_plain(body);
|
|
let event_id = owned_event_id!("$1598361704261elfgc");
|
|
content.relates_to = Some(Relation::Reply(Reply::with_event_id(event_id.clone())));
|
|
|
|
let json_content = Raw::new(&content).unwrap();
|
|
let deser_content = json_content.deserialize().unwrap();
|
|
|
|
assert_matches!(deser_content.msgtype, MessageType::Text(deser_msg));
|
|
assert_eq!(deser_msg.body, body);
|
|
assert_matches!(content.relates_to.unwrap(), Relation::Reply(reply));
|
|
assert_eq!(reply.in_reply_to.event_id, event_id);
|
|
}
|
|
|
|
#[test]
|
|
fn replacement_serialize() {
|
|
let content = assign!(
|
|
RoomMessageEventContent::text_plain("<text msg>"),
|
|
{
|
|
relates_to: Some(Relation::Replacement(
|
|
Replacement::new(
|
|
owned_event_id!("$1598361704261elfgc"),
|
|
RoomMessageEventContent::text_plain("This is the new content.").into(),
|
|
)
|
|
))
|
|
}
|
|
);
|
|
|
|
assert_to_canonical_json_eq!(
|
|
content,
|
|
json!({
|
|
"msgtype": "m.text",
|
|
"body": "<text msg>",
|
|
"m.new_content": {
|
|
"body": "This is the new content.",
|
|
"msgtype": "m.text",
|
|
},
|
|
"m.relates_to": {
|
|
"rel_type": "m.replace",
|
|
"event_id": "$1598361704261elfgc",
|
|
},
|
|
})
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn replacement_deserialize() {
|
|
let json = json!({
|
|
"msgtype": "m.text",
|
|
"body": "<text msg>",
|
|
"m.new_content": {
|
|
"body": "Hello! My name is bar",
|
|
"msgtype": "m.text",
|
|
},
|
|
"m.relates_to": {
|
|
"rel_type": "m.replace",
|
|
"event_id": "$1598361704261elfgc",
|
|
},
|
|
});
|
|
|
|
assert_matches!(
|
|
from_json_value::<RoomMessageEventContent>(json),
|
|
Ok(RoomMessageEventContent {
|
|
msgtype: MessageType::Text(_),
|
|
relates_to: Some(Relation::Replacement(replacement)),
|
|
..
|
|
})
|
|
);
|
|
assert_eq!(replacement.event_id, "$1598361704261elfgc");
|
|
assert_matches!(replacement.new_content.msgtype, MessageType::Text(text));
|
|
assert_eq!(text.body, "Hello! My name is bar");
|
|
}
|
|
|
|
#[test]
|
|
fn replacement_serialization_roundtrip() {
|
|
let body = "<text msg>";
|
|
let mut content = RoomMessageEventContent::text_plain(body);
|
|
let new_body = "This is the new content.";
|
|
let replacement = Replacement::new(
|
|
owned_event_id!("$1598361704261elfgc"),
|
|
RoomMessageEventContent::text_plain(new_body).into(),
|
|
);
|
|
content.relates_to = Some(Relation::Replacement(replacement.clone()));
|
|
|
|
let json_content = Raw::new(&content).unwrap();
|
|
let deser_content = json_content.deserialize().unwrap();
|
|
|
|
assert_matches!(deser_content.msgtype, MessageType::Text(deser_msg));
|
|
assert_eq!(deser_msg.body, body);
|
|
assert_matches!(content.relates_to.unwrap(), Relation::Replacement(deser_replacement));
|
|
assert_eq!(deser_replacement.event_id, replacement.event_id);
|
|
assert_matches!(deser_replacement.new_content.msgtype, MessageType::Text(deser_new_msg));
|
|
assert_eq!(deser_new_msg.body, new_body);
|
|
}
|
|
|
|
#[test]
|
|
fn thread_plain_serialize() {
|
|
let content = assign!(
|
|
RoomMessageEventContent::text_plain("<text msg>"),
|
|
{
|
|
relates_to: Some(Relation::Thread(
|
|
Thread::plain(
|
|
owned_event_id!("$1598361704261elfgc"),
|
|
owned_event_id!("$latesteventid"),
|
|
),
|
|
)),
|
|
}
|
|
);
|
|
|
|
assert_to_canonical_json_eq!(
|
|
content,
|
|
json!({
|
|
"msgtype": "m.text",
|
|
"body": "<text msg>",
|
|
"m.relates_to": {
|
|
"rel_type": "m.thread",
|
|
"event_id": "$1598361704261elfgc",
|
|
"m.in_reply_to": {
|
|
"event_id": "$latesteventid",
|
|
},
|
|
"is_falling_back": true,
|
|
},
|
|
})
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn thread_reply_serialize() {
|
|
let content = assign!(
|
|
RoomMessageEventContent::text_plain("<text msg>"),
|
|
{
|
|
relates_to: Some(Relation::Thread(
|
|
Thread::reply(
|
|
owned_event_id!("$1598361704261elfgc"),
|
|
owned_event_id!("$repliedtoeventid"),
|
|
),
|
|
)),
|
|
}
|
|
);
|
|
|
|
assert_to_canonical_json_eq!(
|
|
content,
|
|
json!({
|
|
"msgtype": "m.text",
|
|
"body": "<text msg>",
|
|
"m.relates_to": {
|
|
"rel_type": "m.thread",
|
|
"event_id": "$1598361704261elfgc",
|
|
"m.in_reply_to": {
|
|
"event_id": "$repliedtoeventid",
|
|
},
|
|
},
|
|
})
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn thread_stable_deserialize() {
|
|
let json = json!({
|
|
"msgtype": "m.text",
|
|
"body": "<text msg>",
|
|
"m.relates_to": {
|
|
"rel_type": "m.thread",
|
|
"event_id": "$1598361704261elfgc",
|
|
},
|
|
});
|
|
|
|
assert_matches!(
|
|
from_json_value::<RoomMessageEventContent>(json),
|
|
Ok(RoomMessageEventContent {
|
|
msgtype: MessageType::Text(_),
|
|
relates_to: Some(Relation::Thread(thread)),
|
|
..
|
|
})
|
|
);
|
|
assert_eq!(thread.event_id, "$1598361704261elfgc");
|
|
assert_matches!(thread.in_reply_to, None);
|
|
assert!(!thread.is_falling_back);
|
|
}
|
|
|
|
#[test]
|
|
fn thread_stable_reply_deserialize() {
|
|
let json = json!({
|
|
"msgtype": "m.text",
|
|
"body": "<text msg>",
|
|
"m.relates_to": {
|
|
"rel_type": "m.thread",
|
|
"event_id": "$1598361704261elfgc",
|
|
"m.in_reply_to": {
|
|
"event_id": "$latesteventid",
|
|
},
|
|
},
|
|
});
|
|
|
|
assert_matches!(
|
|
from_json_value::<RoomMessageEventContent>(json),
|
|
Ok(RoomMessageEventContent {
|
|
msgtype: MessageType::Text(_),
|
|
relates_to: Some(Relation::Thread(thread)),
|
|
..
|
|
})
|
|
);
|
|
assert_eq!(thread.event_id, "$1598361704261elfgc");
|
|
assert_eq!(thread.in_reply_to.unwrap().event_id, "$latesteventid");
|
|
assert!(!thread.is_falling_back);
|
|
}
|
|
|
|
#[test]
|
|
fn thread_unstable_deserialize() {
|
|
let json = json!({
|
|
"msgtype": "m.text",
|
|
"body": "<text msg>",
|
|
"m.relates_to": {
|
|
"rel_type": "io.element.thread",
|
|
"event_id": "$1598361704261elfgc",
|
|
"m.in_reply_to": {
|
|
"event_id": "$latesteventid",
|
|
},
|
|
},
|
|
});
|
|
|
|
assert_matches!(
|
|
from_json_value::<RoomMessageEventContent>(json),
|
|
Ok(RoomMessageEventContent {
|
|
msgtype: MessageType::Text(_),
|
|
relates_to: Some(Relation::Thread(thread)),
|
|
..
|
|
})
|
|
);
|
|
assert_eq!(thread.event_id, "$1598361704261elfgc");
|
|
assert_eq!(thread.in_reply_to.unwrap().event_id, "$latesteventid");
|
|
assert!(!thread.is_falling_back);
|
|
}
|
|
|
|
#[test]
|
|
fn thread_serialization_roundtrip() {
|
|
let body = "<text msg>";
|
|
let mut content = RoomMessageEventContent::text_plain(body);
|
|
let thread =
|
|
Thread::plain(owned_event_id!("$1598361704261elfgc"), owned_event_id!("$latesteventid"));
|
|
content.relates_to = Some(Relation::Thread(thread.clone()));
|
|
|
|
let json_content = Raw::new(&content).unwrap();
|
|
let deser_content = json_content.deserialize().unwrap();
|
|
|
|
assert_matches!(deser_content.msgtype, MessageType::Text(deser_msg));
|
|
assert_eq!(deser_msg.body, body);
|
|
assert_matches!(content.relates_to.unwrap(), Relation::Thread(deser_thread));
|
|
assert_eq!(deser_thread.event_id, thread.event_id);
|
|
assert_eq!(deser_thread.in_reply_to.unwrap().event_id, thread.in_reply_to.unwrap().event_id);
|
|
assert_eq!(deser_thread.is_falling_back, thread.is_falling_back);
|
|
}
|
|
|
|
#[test]
|
|
fn custom_serialization_roundtrip() {
|
|
let relation_json = json!({
|
|
"rel_type": "io.ruma.unknown",
|
|
"event_id": "$related_event",
|
|
"key": "value",
|
|
});
|
|
let content_json = json!({
|
|
"msgtype": "m.text",
|
|
"body": "<text msg>",
|
|
"m.relates_to": relation_json,
|
|
});
|
|
|
|
let content = from_json_value::<RoomMessageEventContent>(content_json.clone()).unwrap();
|
|
assert_let!(
|
|
RoomMessageEventContent { msgtype: MessageType::Text(_), relates_to: Some(relation), .. } =
|
|
&content
|
|
);
|
|
assert_eq!(relation.rel_type().unwrap().as_str(), "io.ruma.unknown");
|
|
assert_eq!(JsonValue::Object(relation.data().into_owned()), relation_json);
|
|
|
|
assert_to_canonical_json_eq!(content, content_json);
|
|
}
|
|
|
|
#[cfg(feature = "unstable-msc3381")]
|
|
#[test]
|
|
fn unstable_poll_start_event_return_relations() {
|
|
let event_content = AnyMessageLikeEventContent::UnstablePollStart(
|
|
UnstablePollStartEventContent::New(assign!(NewUnstablePollStartEventContent::plain_text(
|
|
"A poll",
|
|
UnstablePollStartContentBlock::new(
|
|
"A question",
|
|
vec![
|
|
UnstablePollAnswer::new("id1", "A"),
|
|
UnstablePollAnswer::new("id2", "B")
|
|
].try_into().unwrap()
|
|
)
|
|
), {
|
|
relates_to: Some(RelationWithoutReplacement::Thread(Thread::plain(
|
|
owned_event_id!("$thread_root_id"),
|
|
owned_event_id!("$prev_event_id")
|
|
))),
|
|
})),
|
|
);
|
|
assert_let!(Some(encrypted::Relation::Thread(thread)) = event_content.relation());
|
|
assert_eq!(thread.event_id, event_id!("$thread_root_id"));
|
|
assert!(thread.is_falling_back);
|
|
|
|
assert_let!(Some(in_reply_to) = thread.in_reply_to);
|
|
assert_eq!(in_reply_to.event_id, event_id!("$prev_event_id"));
|
|
}
|
|
|
|
#[cfg(feature = "unstable-msc3381")]
|
|
#[test]
|
|
fn stable_poll_start_event_return_relations() {
|
|
let event_content =
|
|
AnyMessageLikeEventContent::PollStart(assign!(PollStartEventContent::with_plain_text(
|
|
"A poll",
|
|
PollContentBlock::new(
|
|
TextContentBlock::plain("A question"),
|
|
vec![
|
|
PollAnswer::new("id1".to_owned(), TextContentBlock::plain("A")),
|
|
PollAnswer::new("id2".to_owned(), TextContentBlock::plain("B"))
|
|
].try_into().unwrap()
|
|
)
|
|
), {
|
|
relates_to: Some(Relation::Thread(Thread::plain(
|
|
owned_event_id!("$thread_root_id"),
|
|
owned_event_id!("$prev_event_id")
|
|
))),
|
|
}));
|
|
|
|
assert_let!(Some(encrypted::Relation::Thread(thread)) = event_content.relation());
|
|
assert_eq!(thread.event_id, event_id!("$thread_root_id"));
|
|
assert!(thread.is_falling_back);
|
|
|
|
assert_let!(Some(in_reply_to) = thread.in_reply_to);
|
|
assert_eq!(in_reply_to.event_id, event_id!("$prev_event_id"));
|
|
}
|