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(
|
let req = Request::new(
|
||||||
owned_room_id!("!room:server.tld"),
|
owned_room_id!("!room:server.tld"),
|
||||||
&EmptyStateKey,
|
&EmptyStateKey,
|
||||||
&RoomNameEventContent::new(Some("Test room".to_owned())),
|
&RoomNameEventContent::new("Test room".to_owned()),
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.try_into_http_request::<Vec<u8>>(
|
.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
|
- Move the HTML functions in `events::room::message::sanitize` to the ruma-html crate
|
||||||
- The `unstable-sanitize` cargo feature was renamed to `html`
|
- The `unstable-sanitize` cargo feature was renamed to `html`
|
||||||
- Make `via` required in `Space(Child|Parent)EventContent` according to a spec clarification
|
- 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:
|
Improvements:
|
||||||
|
|
||||||
|
@ -48,10 +48,6 @@ compat-empty-string-null = []
|
|||||||
# mandatory. Deserialization will yield a default value like an empty string.
|
# mandatory. Deserialization will yield a default value like an empty string.
|
||||||
compat-optional = []
|
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.
|
# Allow TagInfo to contain a stringified floating-point value for the `order` field.
|
||||||
compat-tag-info = []
|
compat-tag-info = []
|
||||||
|
|
||||||
|
@ -15,42 +15,26 @@ use crate::EmptyStateKey;
|
|||||||
#[ruma_event(type = "m.room.name", kind = State, state_key_type = EmptyStateKey)]
|
#[ruma_event(type = "m.room.name", kind = State, state_key_type = EmptyStateKey)]
|
||||||
pub struct RoomNameEventContent {
|
pub struct RoomNameEventContent {
|
||||||
/// The name of the room.
|
/// The name of the room.
|
||||||
///
|
pub name: String,
|
||||||
/// 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>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RoomNameEventContent {
|
impl RoomNameEventContent {
|
||||||
/// Create a new `RoomNameEventContent` with the given name.
|
/// Create a new `RoomNameEventContent` with the given name.
|
||||||
pub fn new(name: Option<String>) -> Self {
|
pub fn new(name: String) -> Self {
|
||||||
let name = name.filter(|n| !n.is_empty());
|
|
||||||
Self { name }
|
Self { name }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
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 serde_json::{from_value as from_json_value, json, to_value as to_json_value};
|
||||||
|
|
||||||
use super::RoomNameEventContent;
|
use super::RoomNameEventContent;
|
||||||
use crate::OriginalStateEvent;
|
use crate::OriginalStateEvent;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialization_with_optional_fields_as_none() {
|
fn serialization() {
|
||||||
let content = RoomNameEventContent { name: Some("The room name".to_owned()) };
|
let content = RoomNameEventContent { name: "The room name".to_owned() };
|
||||||
|
|
||||||
let actual = to_json_value(content).unwrap();
|
let actual = to_json_value(content).unwrap();
|
||||||
let expected = json!({
|
let expected = json!({
|
||||||
@ -61,99 +45,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialization_with_all_fields() {
|
fn deserialization() {
|
||||||
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();
|
|
||||||
let json_data = json!({
|
let json_data = json!({
|
||||||
"content": {
|
"content": {
|
||||||
"name": "The room name"
|
"name": "The room name"
|
||||||
@ -171,7 +63,7 @@ mod tests {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.content
|
.content
|
||||||
.name,
|
.name,
|
||||||
name
|
"The room name"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,5 +10,5 @@ fn deserialize_initial_state_event() {
|
|||||||
}))
|
}))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_matches!(ev, AnyInitialStateEvent::RoomName(ev));
|
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.
|
# 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
|
# https://github.com/matrix-org/matrix-spec/issues/378#issuecomment-1055831264
|
||||||
compat-unset-avatar = ["ruma-client-api?/compat-unset-avatar"]
|
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`,
|
# Always serialize the threepids response field in `get_3pids::v3::Response`,
|
||||||
# even if its value is an empty list.
|
# even if its value is an empty list.
|
||||||
compat-get-3pids = ["ruma-client-api?/compat-get-3pids"]
|
compat-get-3pids = ["ruma-client-api?/compat-get-3pids"]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user