events: Make name required in RoomNameEventContent
The wording of the spec was confusing but it is indeed required
This commit is contained in:
parent
ae537afb0d
commit
a53bd09b8a
@ -217,7 +217,7 @@ pub mod v3 {
|
||||
let req = Request::new(
|
||||
owned_room_id!("!room:server.tld"),
|
||||
&EmptyStateKey,
|
||||
&RoomNameEventContent::new(Some("Test room".to_owned())),
|
||||
&RoomNameEventContent::new("Test room".to_owned()),
|
||||
)
|
||||
.unwrap()
|
||||
.try_into_http_request::<Vec<u8>>(
|
||||
|
@ -35,6 +35,7 @@ Breaking changes:
|
||||
- Move the HTML functions in `events::room::message::sanitize` to the ruma-html crate
|
||||
- The `unstable-sanitize` cargo feature was renamed to `html`
|
||||
- Make `via` required in `Space(Child|Parent)EventContent` according to a spec clarification
|
||||
- Make `name` required in `RoomNameEventContent`, the wording of the spec was confusing
|
||||
|
||||
Improvements:
|
||||
|
||||
|
@ -48,10 +48,6 @@ compat-empty-string-null = []
|
||||
# mandatory. Deserialization will yield a default value like an empty string.
|
||||
compat-optional = []
|
||||
|
||||
# Unset the room name by sending an empty string,
|
||||
# c.f. https://github.com/matrix-org/matrix-spec/issues/1632
|
||||
compat-unset-room-name = []
|
||||
|
||||
# Allow TagInfo to contain a stringified floating-point value for the `order` field.
|
||||
compat-tag-info = []
|
||||
|
||||
|
@ -15,42 +15,26 @@ use crate::EmptyStateKey;
|
||||
#[ruma_event(type = "m.room.name", kind = State, state_key_type = EmptyStateKey)]
|
||||
pub struct RoomNameEventContent {
|
||||
/// The name of the room.
|
||||
///
|
||||
/// If you activate the `compat-unset-room-name` feature, this field being `None` will result
|
||||
/// in an empty string in serialization, (c.f.
|
||||
/// <https://github.com/matrix-org/matrix-spec/issues/1632>).
|
||||
#[serde(default, deserialize_with = "ruma_common::serde::empty_string_as_none")]
|
||||
#[cfg_attr(
|
||||
feature = "compat-unset-room-name",
|
||||
serde(serialize_with = "ruma_common::serde::none_as_empty_string")
|
||||
)]
|
||||
#[cfg_attr(
|
||||
not(feature = "compat-unset-room-name"),
|
||||
serde(skip_serializing_if = "Option::is_none")
|
||||
)]
|
||||
pub name: Option<String>,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl RoomNameEventContent {
|
||||
/// Create a new `RoomNameEventContent` with the given name.
|
||||
pub fn new(name: Option<String>) -> Self {
|
||||
let name = name.filter(|n| !n.is_empty());
|
||||
pub fn new(name: String) -> Self {
|
||||
Self { name }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use assert_matches2::assert_matches;
|
||||
use ruma_common::serde::Raw;
|
||||
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
|
||||
|
||||
use super::RoomNameEventContent;
|
||||
use crate::OriginalStateEvent;
|
||||
|
||||
#[test]
|
||||
fn serialization_with_optional_fields_as_none() {
|
||||
let content = RoomNameEventContent { name: Some("The room name".to_owned()) };
|
||||
fn serialization() {
|
||||
let content = RoomNameEventContent { name: "The room name".to_owned() };
|
||||
|
||||
let actual = to_json_value(content).unwrap();
|
||||
let expected = json!({
|
||||
@ -61,99 +45,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialization_with_all_fields() {
|
||||
let content = RoomNameEventContent { name: Some("The room name".to_owned()) };
|
||||
|
||||
let actual = to_json_value(content).unwrap();
|
||||
let expected = json!({
|
||||
"name": "The room name",
|
||||
});
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn absent_field_as_none() {
|
||||
let json_data = json!({
|
||||
"content": {},
|
||||
"event_id": "$h29iv0s8:example.com",
|
||||
"origin_server_ts": 1,
|
||||
"room_id": "!n8f893n9:example.com",
|
||||
"sender": "@carl:example.com",
|
||||
"state_key": "",
|
||||
"type": "m.room.name"
|
||||
});
|
||||
assert_eq!(
|
||||
from_json_value::<OriginalStateEvent<RoomNameEventContent>>(json_data)
|
||||
.unwrap()
|
||||
.content
|
||||
.name,
|
||||
None
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn json_with_empty_name_creates_content_as_none() {
|
||||
let long_content_json = json!({ "name": "" });
|
||||
let from_raw: Raw<RoomNameEventContent> = from_json_value(long_content_json).unwrap();
|
||||
assert_matches!(from_raw.deserialize().unwrap(), RoomNameEventContent { name: None });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn new_with_empty_name_creates_content_as_none() {
|
||||
assert_matches!(
|
||||
RoomNameEventContent::new(Some("".to_owned())),
|
||||
RoomNameEventContent { name: None }
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn null_field_as_none() {
|
||||
let json_data = json!({
|
||||
"content": {
|
||||
"name": null
|
||||
},
|
||||
"event_id": "$h29iv0s8:example.com",
|
||||
"origin_server_ts": 1,
|
||||
"room_id": "!n8f893n9:example.com",
|
||||
"sender": "@carl:example.com",
|
||||
"state_key": "",
|
||||
"type": "m.room.name"
|
||||
});
|
||||
assert_eq!(
|
||||
from_json_value::<OriginalStateEvent<RoomNameEventContent>>(json_data)
|
||||
.unwrap()
|
||||
.content
|
||||
.name,
|
||||
None
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_string_as_none() {
|
||||
let json_data = json!({
|
||||
"content": {
|
||||
"name": ""
|
||||
},
|
||||
"event_id": "$h29iv0s8:example.com",
|
||||
"origin_server_ts": 1,
|
||||
"room_id": "!n8f893n9:example.com",
|
||||
"sender": "@carl:example.com",
|
||||
"state_key": "",
|
||||
"type": "m.room.name"
|
||||
});
|
||||
assert_eq!(
|
||||
from_json_value::<OriginalStateEvent<RoomNameEventContent>>(json_data)
|
||||
.unwrap()
|
||||
.content
|
||||
.name,
|
||||
None
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nonempty_field_as_some() {
|
||||
let name = "The room name".try_into().ok();
|
||||
fn deserialization() {
|
||||
let json_data = json!({
|
||||
"content": {
|
||||
"name": "The room name"
|
||||
@ -171,7 +63,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.content
|
||||
.name,
|
||||
name
|
||||
"The room name"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -10,5 +10,5 @@ fn deserialize_initial_state_event() {
|
||||
}))
|
||||
.unwrap();
|
||||
assert_matches!(ev, AnyInitialStateEvent::RoomName(ev));
|
||||
assert_eq!(ev.content.name.as_deref(), Some("foo"));
|
||||
assert_eq!(ev.content.name, "foo");
|
||||
}
|
||||
|
@ -127,9 +127,6 @@ compat-optional = [
|
||||
# Unset avatars by sending an empty string, same as what Element Web does, c.f.
|
||||
# https://github.com/matrix-org/matrix-spec/issues/378#issuecomment-1055831264
|
||||
compat-unset-avatar = ["ruma-client-api?/compat-unset-avatar"]
|
||||
# Unset the room name by sending an empty string,
|
||||
# c.f. https://github.com/matrix-org/matrix-spec/issues/1632
|
||||
compat-unset-room-name = ["ruma-events?/compat-unset-room-name"]
|
||||
# Always serialize the threepids response field in `get_3pids::v3::Response`,
|
||||
# even if its value is an empty list.
|
||||
compat-get-3pids = ["ruma-client-api?/compat-get-3pids"]
|
||||
|
Loading…
x
Reference in New Issue
Block a user