Fix failing deserialization when encountering an unknown field

This commit is contained in:
Ragotzy.devin 2020-06-15 18:34:58 -04:00 committed by GitHub
parent f2f283c965
commit f4665761be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 33 deletions

View File

@ -212,12 +212,14 @@ fn expand_deserialize_event(
where where
D: ::serde::de::Deserializer<'de>, D: ::serde::de::Deserializer<'de>,
{ {
#[derive(serde::Deserialize)] #[derive(::serde::Deserialize)]
#[serde(field_identifier, rename_all = "snake_case")] #[serde(field_identifier, rename_all = "snake_case")]
enum Field { enum Field {
// since this is represented as an enum we have to add it so the JSON picks it up // since this is represented as an enum we have to add it so the JSON picks it up
Type, Type,
#( #enum_variants ),* #( #enum_variants, )*
#[serde(other)]
Unknown,
} }
/// Visits the fields of an event struct to handle deserialization of /// Visits the fields of an event struct to handle deserialization of
@ -242,6 +244,7 @@ fn expand_deserialize_event(
while let Some(key) = map.next_key()? { while let Some(key) = map.next_key()? {
match key { match key {
Field::Unknown => continue,
Field::Type => { Field::Type => {
if event_type.is_some() { if event_type.is_some() {
return Err(::serde::de::Error::duplicate_field("type")); return Err(::serde::de::Error::duplicate_field("type"));

View File

@ -7,10 +7,29 @@ use js_int::UInt;
use matches::assert_matches; use matches::assert_matches;
use ruma_events::{ use ruma_events::{
room::{aliases::AliasesEventContent, avatar::AvatarEventContent, ImageInfo, ThumbnailInfo}, room::{aliases::AliasesEventContent, avatar::AvatarEventContent, ImageInfo, ThumbnailInfo},
AnyStateEventContent, EventJson, StateEvent, UnsignedData, AnyStateEventContent, EventJson, StateEvent, StateEventStub, UnsignedData,
}; };
use ruma_identifiers::{EventId, RoomAliasId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomAliasId, RoomId, UserId};
use serde_json::{from_value as from_json_value, json, to_value as to_json_value}; use serde_json::{
from_value as from_json_value, json, to_value as to_json_value, Value as JsonValue,
};
fn aliases_event_with_prev_content() -> JsonValue {
json!({
"content": {
"aliases": [ "#somewhere:localhost" ]
},
"event_id": "$h29iv0s8:example.com",
"origin_server_ts": 1,
"prev_content": {
"aliases": [ "#inner:localhost" ]
},
"room_id": "!roomid:room.com",
"sender": "@carl:example.com",
"state_key": "",
"type": "m.room.aliases"
})
}
#[test] #[test]
fn serialize_aliases_with_prev_content() { fn serialize_aliases_with_prev_content() {
@ -21,7 +40,7 @@ fn serialize_aliases_with_prev_content() {
event_id: EventId::try_from("$h29iv0s8:example.com").unwrap(), event_id: EventId::try_from("$h29iv0s8:example.com").unwrap(),
origin_server_ts: UNIX_EPOCH + Duration::from_millis(1), origin_server_ts: UNIX_EPOCH + Duration::from_millis(1),
prev_content: Some(AnyStateEventContent::RoomAliases(AliasesEventContent { prev_content: Some(AnyStateEventContent::RoomAliases(AliasesEventContent {
aliases: vec![RoomAliasId::try_from("#somewhere:localhost").unwrap()], aliases: vec![RoomAliasId::try_from("#inner:localhost").unwrap()],
})), })),
room_id: RoomId::try_from("!roomid:room.com").unwrap(), room_id: RoomId::try_from("!roomid:room.com").unwrap(),
sender: UserId::try_from("@carl:example.com").unwrap(), sender: UserId::try_from("@carl:example.com").unwrap(),
@ -30,20 +49,7 @@ fn serialize_aliases_with_prev_content() {
}; };
let actual = to_json_value(&aliases_event).unwrap(); let actual = to_json_value(&aliases_event).unwrap();
let expected = json!({ let expected = aliases_event_with_prev_content();
"content": {
"aliases": [ "#somewhere:localhost" ]
},
"event_id": "$h29iv0s8:example.com",
"origin_server_ts": 1,
"prev_content": {
"aliases": [ "#somewhere:localhost" ]
},
"room_id": "!roomid:room.com",
"sender": "@carl:example.com",
"state_key": "",
"type": "m.room.aliases",
});
assert_eq!(actual, expected); assert_eq!(actual, expected);
} }
@ -97,20 +103,7 @@ fn deserialize_aliases_content() {
#[test] #[test]
fn deserialize_aliases_with_prev_content() { fn deserialize_aliases_with_prev_content() {
let json_data = json!({ let json_data = aliases_event_with_prev_content();
"content": {
"aliases": [ "#somewhere:localhost" ]
},
"event_id": "$h29iv0s8:example.com",
"origin_server_ts": 1,
"prev_content": {
"aliases": [ "#inner:localhost" ]
},
"room_id": "!roomid:room.com",
"sender": "@carl:example.com",
"state_key": "",
"type": "m.room.aliases"
});
assert_matches!( assert_matches!(
from_json_value::<EventJson<StateEvent<AnyStateEventContent>>>(json_data) from_json_value::<EventJson<StateEvent<AnyStateEventContent>>>(json_data)
@ -137,6 +130,31 @@ fn deserialize_aliases_with_prev_content() {
); );
} }
#[test]
fn deserialize_aliases_stub_with_room_id() {
let json_data = aliases_event_with_prev_content();
assert_matches!(
from_json_value::<StateEventStub<AnyStateEventContent>>(json_data)
.unwrap(),
StateEventStub {
content: AnyStateEventContent::RoomAliases(content),
event_id,
origin_server_ts,
prev_content: Some(AnyStateEventContent::RoomAliases(prev_content)),
sender,
state_key,
unsigned,
} if content.aliases == vec![RoomAliasId::try_from("#somewhere:localhost").unwrap()]
&& event_id == EventId::try_from("$h29iv0s8:example.com").unwrap()
&& origin_server_ts == UNIX_EPOCH + Duration::from_millis(1)
&& prev_content.aliases == vec![RoomAliasId::try_from("#inner:localhost").unwrap()]
&& sender == UserId::try_from("@carl:example.com").unwrap()
&& state_key == ""
&& unsigned.is_empty()
);
}
#[test] #[test]
fn deserialize_avatar_without_prev_content() { fn deserialize_avatar_without_prev_content() {
let json_data = json!({ let json_data = json!({