use std::borrow::Cow; use assign::assign; use js_int::uint; use matches::assert_matches; use ruma_common::{ event_id, events::{ key::verification::VerificationMethod, room::message::{ AudioMessageEventContent, InReplyTo, KeyVerificationRequestEventContent, MessageType, Relation, RoomMessageEvent, RoomMessageEventContent, TextMessageEventContent, }, MessageLikeUnsigned, }, mxc_uri, room_id, user_id, DeviceId, MilliSecondsSinceUnixEpoch, }; use serde_json::{from_value as from_json_value, json, to_value as to_json_value}; macro_rules! json_object { ( $($key:expr => $value:expr),* $(,)? ) => { { let mut _map = serde_json::Map::::new(); $( let _ = _map.insert($key, $value); )* _map } }; } #[test] fn serialization() { let ev = RoomMessageEvent { content: RoomMessageEventContent::new(MessageType::Audio(AudioMessageEventContent::plain( "test".into(), mxc_uri!("mxc://example.org/ffed755USFFxlgbQYZGtryd").to_owned(), None, ))), event_id: event_id!("$143273582443PhrSn:example.org").to_owned(), origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(10_000)), room_id: room_id!("!testroomid:example.org").to_owned(), sender: user_id!("@user:example.org").to_owned(), unsigned: MessageLikeUnsigned::default(), }; assert_eq!( to_json_value(ev).unwrap(), json!({ "type": "m.room.message", "event_id": "$143273582443PhrSn:example.org", "origin_server_ts": 10_000, "room_id": "!testroomid:example.org", "sender": "@user:example.org", "content": { "body": "test", "msgtype": "m.audio", "url": "mxc://example.org/ffed755USFFxlgbQYZGtryd", } }) ); } #[test] fn content_serialization() { let message_event_content = RoomMessageEventContent::new(MessageType::Audio(AudioMessageEventContent::plain( "test".into(), mxc_uri!("mxc://example.org/ffed755USFFxlgbQYZGtryd").to_owned(), None, ))); assert_eq!( to_json_value(&message_event_content).unwrap(), json!({ "body": "test", "msgtype": "m.audio", "url": "mxc://example.org/ffed755USFFxlgbQYZGtryd" }) ); } #[test] fn custom_msgtype_serialization() { let json_data = json_object! { "custom_field".into() => json!("baba"), "another_one".into() => json!("abab"), }; let custom_msgtype = MessageType::new("my_custom_msgtype", "my message body".into(), json_data).unwrap(); assert_eq!( to_json_value(&custom_msgtype).unwrap(), json!({ "msgtype": "my_custom_msgtype", "body": "my message body", "custom_field": "baba", "another_one": "abab", }) ); } #[test] fn custom_content_deserialization() { let json_data = json!({ "msgtype": "my_custom_msgtype", "body": "my custom message", "custom_field": "baba", "another_one": "abab", }); let expected_json_data = json_object! { "custom_field".into() => json!("baba"), "another_one".into() => json!("abab"), }; let custom_event: MessageType = from_json_value(json_data).unwrap(); assert_eq!(custom_event.msgtype(), "my_custom_msgtype"); assert_eq!(custom_event.body(), "my custom message"); assert_eq!(custom_event.data(), Cow::Owned(expected_json_data)); } #[test] fn formatted_body_serialization() { let message_event_content = RoomMessageEventContent::text_html("Hello, World!", "Hello, World!"); assert_eq!( to_json_value(&message_event_content).unwrap(), json!({ "body": "Hello, World!", "msgtype": "m.text", "format": "org.matrix.custom.html", "formatted_body": "Hello, World!", }) ); } #[test] fn plain_text_content_serialization() { let message_event_content = RoomMessageEventContent::text_plain("> <@test:example.com> test\n\ntest reply"); assert_eq!( to_json_value(&message_event_content).unwrap(), json!({ "body": "> <@test:example.com> test\n\ntest reply", "msgtype": "m.text" }) ); } #[test] #[cfg(feature = "markdown")] fn markdown_content_serialization() { let formatted_message = RoomMessageEventContent::new(MessageType::Text( TextMessageEventContent::markdown("Testing **bold** and _italic_!"), )); assert_eq!( to_json_value(&formatted_message).unwrap(), json!({ "body": "Testing **bold** and _italic_!", "formatted_body": "

Testing bold and italic!

\n", "format": "org.matrix.custom.html", "msgtype": "m.text" }) ); let plain_message_simple = RoomMessageEventContent::new(MessageType::Text( TextMessageEventContent::markdown("Testing a simple phrase…"), )); assert_eq!( to_json_value(&plain_message_simple).unwrap(), json!({ "body": "Testing a simple phrase…", "msgtype": "m.text" }) ); let plain_message_paragraphs = RoomMessageEventContent::new(MessageType::Text( TextMessageEventContent::markdown("Testing\n\nSeveral\n\nParagraphs."), )); assert_eq!( to_json_value(&plain_message_paragraphs).unwrap(), json!({ "body": "Testing\n\nSeveral\n\nParagraphs.", "formatted_body": "

Testing

\n

Several

\n

Paragraphs.

\n", "format": "org.matrix.custom.html", "msgtype": "m.text" }) ); } #[test] fn relates_to_content_serialization() { let message_event_content = assign!(RoomMessageEventContent::text_plain("> <@test:example.com> test\n\ntest reply"), { relates_to: Some(Relation::Reply { in_reply_to: InReplyTo::new( event_id!("$15827405538098VGFWH:example.com").to_owned(), ), }), }); let json_data = json!({ "body": "> <@test:example.com> test\n\ntest reply", "msgtype": "m.text", "m.relates_to": { "m.in_reply_to": { "event_id": "$15827405538098VGFWH:example.com" } } }); assert_eq!(to_json_value(&message_event_content).unwrap(), json_data); } #[test] #[cfg(not(feature = "unstable-msc2676"))] fn edit_deserialization_061() { let json_data = json!({ "body": "s/foo/bar", "msgtype": "m.text", "m.relates_to": { "rel_type": "m.replace", "event_id": event_id!("$1598361704261elfgc:localhost"), }, "m.new_content": { "body": "bar", }, }); assert_matches!( from_json_value::(json_data).unwrap(), RoomMessageEventContent { msgtype: MessageType::Text(TextMessageEventContent { body, formatted: None, .. }), relates_to: Some(_), .. } if body == "s/foo/bar" ); } #[test] #[cfg(feature = "unstable-msc2676")] fn edit_deserialization_future() { use ruma_common::events::room::message::Replacement; let ev_id = event_id!("$1598361704261elfgc:localhost"); let json_data = json!({ "body": "s/foo/bar", "msgtype": "m.text", "m.relates_to": { "rel_type": "m.replace", "event_id": ev_id, }, "m.new_content": { "body": "bar", "msgtype": "m.text", }, }); assert_matches!( from_json_value::(json_data).unwrap(), RoomMessageEventContent { msgtype: MessageType::Text(TextMessageEventContent { body, formatted: None, .. }), relates_to: Some(Relation::Replacement(Replacement { event_id, new_content, .. })), .. } if body == "s/foo/bar" && event_id == ev_id && matches!( &*new_content, RoomMessageEventContent { msgtype: MessageType::Text(TextMessageEventContent { body, formatted: None, .. }), .. } if body == "bar" ) ); } #[test] fn verification_request_deserialization() { let user_id = user_id!("@example2:localhost"); let device_id: Box = "XOWLHHFSWM".into(); let json_data = json!({ "body": "@example:localhost is requesting to verify your key, ...", "msgtype": "m.key.verification.request", "to": user_id, "from_device": device_id, "methods": [ "m.sas.v1", "m.qr_code.show.v1", "m.reciprocate.v1" ] }); assert_matches!( from_json_value::(json_data).unwrap(), RoomMessageEventContent { msgtype: MessageType::VerificationRequest(KeyVerificationRequestEventContent { body, to, from_device, methods, .. }), .. } if body == "@example:localhost is requesting to verify your key, ..." && to == user_id && from_device == device_id && methods.contains(&VerificationMethod::SasV1) ); } #[test] fn verification_request_serialization() { let user_id = user_id!("@example2:localhost").to_owned(); let device_id: Box = "XOWLHHFSWM".into(); let body = "@example:localhost is requesting to verify your key, ...".to_owned(); let methods = vec![VerificationMethod::SasV1, "m.qr_code.show.v1".into(), "m.reciprocate.v1".into()]; let json_data = json!({ "body": body, "msgtype": "m.key.verification.request", "to": user_id, "from_device": device_id, "methods": methods }); let content = MessageType::VerificationRequest(KeyVerificationRequestEventContent::new( body, methods, device_id, user_id, )); assert_eq!(to_json_value(&content).unwrap(), json_data,); } #[test] fn content_deserialization() { let json_data = json!({ "body": "test", "msgtype": "m.audio", "url": "mxc://example.org/ffed755USFFxlgbQYZGtryd" }); assert_matches!( from_json_value::(json_data) .unwrap(), RoomMessageEventContent { msgtype: MessageType::Audio(AudioMessageEventContent { body, info: None, url: Some(url), file: None, .. }), .. } if body == "test" && url == "mxc://example.org/ffed755USFFxlgbQYZGtryd" ); } #[test] fn content_deserialization_failure() { let json_data = json!({ "body": "test","msgtype": "m.location", "url": "http://example.com/audio.mp3" }); assert!(from_json_value::(json_data).is_err()); }