events: Update types according to changes in MSC3381
This commit is contained in:
parent
fbf99fcc53
commit
61c23491c6
@ -72,13 +72,13 @@ event_enum! {
|
||||
"org.matrix.msc1767.message" => super::message,
|
||||
#[cfg(feature = "unstable-msc3381")]
|
||||
#[ruma_enum(alias = "m.poll.start")]
|
||||
"org.matrix.msc3381.poll.start" => super::poll::start,
|
||||
"org.matrix.msc3381.v2.poll.start" => super::poll::start,
|
||||
#[cfg(feature = "unstable-msc3381")]
|
||||
#[ruma_enum(alias = "m.poll.response")]
|
||||
"org.matrix.msc3381.poll.response" => super::poll::response,
|
||||
"org.matrix.msc3381.v2.poll.response" => super::poll::response,
|
||||
#[cfg(feature = "unstable-msc3381")]
|
||||
#[ruma_enum(alias = "m.poll.end")]
|
||||
"org.matrix.msc3381.poll.end" => super::poll::end,
|
||||
"org.matrix.msc3381.v2.poll.end" => super::poll::end,
|
||||
#[cfg(feature = "unstable-msc2677")]
|
||||
"m.reaction" => super::reaction,
|
||||
"m.room.encrypted" => super::room::encrypted,
|
||||
|
@ -271,8 +271,8 @@ pub struct TextRepresentation {
|
||||
#[cfg(feature = "unstable-msc3554")]
|
||||
#[serde(
|
||||
rename = "org.matrix.msc3554.lang",
|
||||
default = "Text::default_lang",
|
||||
skip_serializing_if = "Text::is_default_lang"
|
||||
default = "TextRepresentation::default_lang",
|
||||
skip_serializing_if = "TextRepresentation::is_default_lang"
|
||||
)]
|
||||
pub lang: String,
|
||||
}
|
||||
@ -316,10 +316,12 @@ impl TextRepresentation {
|
||||
mime == "text/plain"
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc3554")]
|
||||
fn default_lang() -> String {
|
||||
"en".to_owned()
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc3554")]
|
||||
fn is_default_lang(lang: &str) -> bool {
|
||||
lang == "en"
|
||||
}
|
||||
|
@ -1,18 +1,43 @@
|
||||
//! Types for the [`m.poll.end`] event.
|
||||
|
||||
use std::{
|
||||
collections::{btree_map, BTreeMap},
|
||||
ops::Deref,
|
||||
};
|
||||
|
||||
use js_int::UInt;
|
||||
use ruma_macros::EventContent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{events::relation::Reference, OwnedEventId};
|
||||
use crate::{
|
||||
events::{message::TextContentBlock, relation::Reference},
|
||||
OwnedEventId,
|
||||
};
|
||||
|
||||
/// The payload for a poll end event.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, EventContent)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
#[ruma_event(type = "org.matrix.msc3381.poll.end", alias = "m.poll.end", kind = MessageLike)]
|
||||
#[ruma_event(type = "org.matrix.msc3381.v2.poll.end", alias = "m.poll.end", kind = MessageLike)]
|
||||
pub struct PollEndEventContent {
|
||||
/// The poll end content of the message.
|
||||
#[serde(rename = "org.matrix.msc3381.poll.end", alias = "m.poll.end")]
|
||||
pub poll_end: PollEndContent,
|
||||
/// The text representation of the results.
|
||||
#[serde(rename = "org.matrix.msc1767.text")]
|
||||
pub text: TextContentBlock,
|
||||
|
||||
/// The sender's perspective of the results.
|
||||
#[serde(
|
||||
rename = "org.matrix.msc3381.v2.poll.results",
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub poll_results: Option<PollResultsContentBlock>,
|
||||
|
||||
/// Whether this message is automated.
|
||||
#[cfg(feature = "unstable-msc3955")]
|
||||
#[serde(
|
||||
default,
|
||||
skip_serializing_if = "crate::serde::is_default",
|
||||
rename = "org.matrix.msc1767.automated"
|
||||
)]
|
||||
pub automated: bool,
|
||||
|
||||
/// Information about the poll start event this responds to.
|
||||
#[serde(rename = "m.relates_to")]
|
||||
@ -20,23 +45,63 @@ pub struct PollEndEventContent {
|
||||
}
|
||||
|
||||
impl PollEndEventContent {
|
||||
/// Creates a new `PollEndEventContent` that responds to the given poll start event ID,
|
||||
/// with the given poll end content.
|
||||
pub fn new(poll_end: PollEndContent, poll_start_id: OwnedEventId) -> Self {
|
||||
Self { poll_end, relates_to: Reference::new(poll_start_id) }
|
||||
/// Creates a new `PollEndEventContent` with the given fallback representation and
|
||||
/// that responds to the given poll start event ID.
|
||||
pub fn new(text: TextContentBlock, poll_start_id: OwnedEventId) -> Self {
|
||||
Self {
|
||||
text,
|
||||
poll_results: None,
|
||||
#[cfg(feature = "unstable-msc3955")]
|
||||
automated: false,
|
||||
relates_to: Reference::new(poll_start_id),
|
||||
}
|
||||
}
|
||||
|
||||
/// Poll end content.
|
||||
/// Creates a new `PollEndEventContent` with the given plain text fallback representation and
|
||||
/// that responds to the given poll start event ID.
|
||||
pub fn with_plain_text(plain_text: impl Into<String>, poll_start_id: OwnedEventId) -> Self {
|
||||
Self {
|
||||
text: TextContentBlock::plain(plain_text),
|
||||
poll_results: None,
|
||||
#[cfg(feature = "unstable-msc3955")]
|
||||
automated: false,
|
||||
relates_to: Reference::new(poll_start_id),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A block for the results of a poll.
|
||||
///
|
||||
/// This is currently empty.
|
||||
/// This is a map of answer ID to number of votes.
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
pub struct PollEndContent {}
|
||||
pub struct PollResultsContentBlock(BTreeMap<String, UInt>);
|
||||
|
||||
impl PollEndContent {
|
||||
/// Creates a new empty `PollEndContent`.
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
impl From<BTreeMap<String, UInt>> for PollResultsContentBlock {
|
||||
fn from(value: BTreeMap<String, UInt>) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for PollResultsContentBlock {
|
||||
type Item = (String, UInt);
|
||||
type IntoIter = btree_map::IntoIter<String, UInt>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.0.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<(String, UInt)> for PollResultsContentBlock {
|
||||
fn from_iter<T: IntoIterator<Item = (String, UInt)>>(iter: T) -> Self {
|
||||
Self(BTreeMap::from_iter(iter))
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for PollResultsContentBlock {
|
||||
type Target = BTreeMap<String, UInt>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
//! Types for the [`m.poll.response`] event.
|
||||
|
||||
use std::{ops::Deref, vec};
|
||||
|
||||
use ruma_macros::EventContent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -8,11 +10,20 @@ use crate::{events::relation::Reference, OwnedEventId};
|
||||
/// The payload for a poll response event.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, EventContent)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
#[ruma_event(type = "org.matrix.msc3381.poll.response", alias = "m.poll.response", kind = MessageLike)]
|
||||
#[ruma_event(type = "org.matrix.msc3381.v2.poll.response", alias = "m.poll.response", kind = MessageLike)]
|
||||
pub struct PollResponseEventContent {
|
||||
/// The poll response content of the message.
|
||||
#[serde(rename = "org.matrix.msc3381.poll.response", alias = "m.poll.response")]
|
||||
pub poll_response: PollResponseContent,
|
||||
/// The user's selection.
|
||||
#[serde(rename = "org.matrix.msc3381.v2.selections")]
|
||||
pub selections: SelectionsContentBlock,
|
||||
|
||||
/// Whether this message is automated.
|
||||
#[cfg(feature = "unstable-msc3955")]
|
||||
#[serde(
|
||||
default,
|
||||
skip_serializing_if = "crate::serde::is_default",
|
||||
rename = "org.matrix.msc1767.automated"
|
||||
)]
|
||||
pub automated: bool,
|
||||
|
||||
/// Information about the poll start event this responds to.
|
||||
#[serde(rename = "m.relates_to")]
|
||||
@ -22,27 +33,53 @@ pub struct PollResponseEventContent {
|
||||
impl PollResponseEventContent {
|
||||
/// Creates a new `PollResponseEventContent` that responds to the given poll start event ID,
|
||||
/// with the given poll response content.
|
||||
pub fn new(poll_response: PollResponseContent, poll_start_id: OwnedEventId) -> Self {
|
||||
Self { poll_response, relates_to: Reference::new(poll_start_id) }
|
||||
pub fn new(selections: SelectionsContentBlock, poll_start_id: OwnedEventId) -> Self {
|
||||
Self {
|
||||
selections,
|
||||
#[cfg(feature = "unstable-msc3955")]
|
||||
automated: false,
|
||||
relates_to: Reference::new(poll_start_id),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Poll response content.
|
||||
/// A block for selections content.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
pub struct PollResponseContent {
|
||||
/// The IDs of the selected answers of the poll.
|
||||
///
|
||||
/// It should be truncated to `max_selections` from the related poll start event.
|
||||
///
|
||||
/// If this is an empty array or includes unknown IDs, this vote should be considered as
|
||||
/// spoiled.
|
||||
pub answers: Vec<String>,
|
||||
pub struct SelectionsContentBlock(Vec<String>);
|
||||
|
||||
impl SelectionsContentBlock {
|
||||
/// Whether this `SelectionsContentBlock` is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl PollResponseContent {
|
||||
/// Creates a new `PollResponseContent` with the given answers.
|
||||
pub fn new(answers: Vec<String>) -> Self {
|
||||
Self { answers }
|
||||
impl From<Vec<String>> for SelectionsContentBlock {
|
||||
fn from(value: Vec<String>) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for SelectionsContentBlock {
|
||||
type Item = String;
|
||||
type IntoIter = vec::IntoIter<String>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.0.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<String> for SelectionsContentBlock {
|
||||
fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
|
||||
Self(Vec::from_iter(iter))
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for SelectionsContentBlock {
|
||||
type Target = [String];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
//! Types for the [`m.poll.start`] event.
|
||||
|
||||
use std::ops::Deref;
|
||||
|
||||
use js_int::{uint, UInt};
|
||||
use ruma_macros::EventContent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -13,37 +15,59 @@ use crate::{events::message::TextContentBlock, serde::StringEnum, PrivOwnedStr};
|
||||
/// The payload for a poll start event.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, EventContent)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
#[ruma_event(type = "org.matrix.msc3381.poll.start", alias = "m.poll.start", kind = MessageLike)]
|
||||
#[ruma_event(type = "org.matrix.msc3381.v2.poll.start", alias = "m.poll.start", kind = MessageLike)]
|
||||
pub struct PollStartEventContent {
|
||||
/// The poll start content of the message.
|
||||
#[serde(rename = "org.matrix.msc3381.poll.start", alias = "m.poll.start")]
|
||||
pub poll_start: PollStartContent,
|
||||
/// The poll content of the message.
|
||||
#[serde(rename = "org.matrix.msc3381.v2.poll")]
|
||||
pub poll: PollContentBlock,
|
||||
|
||||
/// Optional fallback text representation of the message, for clients that don't support polls.
|
||||
#[serde(
|
||||
rename = "org.matrix.msc1767.text",
|
||||
default,
|
||||
skip_serializing_if = "TextContentBlock::is_empty"
|
||||
)]
|
||||
/// Text representation of the message, for clients that don't support polls.
|
||||
#[serde(rename = "org.matrix.msc1767.text")]
|
||||
pub text: TextContentBlock,
|
||||
|
||||
/// Whether this message is automated.
|
||||
#[cfg(feature = "unstable-msc3955")]
|
||||
#[serde(
|
||||
default,
|
||||
skip_serializing_if = "crate::serde::is_default",
|
||||
rename = "org.matrix.msc1767.automated"
|
||||
)]
|
||||
pub automated: bool,
|
||||
}
|
||||
|
||||
impl PollStartEventContent {
|
||||
/// Creates a new `PollStartEventContent` with the given poll start content.
|
||||
pub fn new(poll_start: PollStartContent) -> Self {
|
||||
Self { poll_start, text: Default::default() }
|
||||
/// Creates a new `PollStartEventContent` with the given fallback representation and poll
|
||||
/// content.
|
||||
pub fn new(text: TextContentBlock, poll: PollContentBlock) -> Self {
|
||||
Self {
|
||||
poll,
|
||||
text,
|
||||
#[cfg(feature = "unstable-msc3955")]
|
||||
automated: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Poll start content.
|
||||
/// Creates a new `PollStartEventContent` with the given plain text fallback
|
||||
/// representation and poll content.
|
||||
pub fn with_plain_text(plain_text: impl Into<String>, poll: PollContentBlock) -> Self {
|
||||
Self {
|
||||
poll,
|
||||
text: TextContentBlock::plain(plain_text),
|
||||
#[cfg(feature = "unstable-msc3955")]
|
||||
automated: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A block for poll content.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
pub struct PollStartContent {
|
||||
pub struct PollContentBlock {
|
||||
/// The question of the poll.
|
||||
pub question: PollQuestion,
|
||||
|
||||
/// The kind of the poll.
|
||||
#[serde(default)]
|
||||
#[serde(default, skip_serializing_if = "crate::serde::is_default")]
|
||||
pub kind: PollKind,
|
||||
|
||||
/// The maximum number of responses a user is able to select.
|
||||
@ -52,8 +76,8 @@ pub struct PollStartContent {
|
||||
///
|
||||
/// Defaults to `1`.
|
||||
#[serde(
|
||||
default = "PollStartContent::default_max_selections",
|
||||
skip_serializing_if = "PollStartContent::max_selections_is_default"
|
||||
default = "PollContentBlock::default_max_selections",
|
||||
skip_serializing_if = "PollContentBlock::max_selections_is_default"
|
||||
)]
|
||||
pub max_selections: UInt,
|
||||
|
||||
@ -61,12 +85,12 @@ pub struct PollStartContent {
|
||||
pub answers: PollAnswers,
|
||||
}
|
||||
|
||||
impl PollStartContent {
|
||||
/// Creates a new `PollStartContent` with the given question, kind, and answers.
|
||||
pub fn new(question: TextContentBlock, kind: PollKind, answers: PollAnswers) -> Self {
|
||||
impl PollContentBlock {
|
||||
/// Creates a new `PollStartContent` with the given question and answers.
|
||||
pub fn new(question: TextContentBlock, answers: PollAnswers) -> Self {
|
||||
Self {
|
||||
question: question.into(),
|
||||
kind,
|
||||
kind: Default::default(),
|
||||
max_selections: Self::default_max_selections(),
|
||||
answers,
|
||||
}
|
||||
@ -103,11 +127,11 @@ impl From<TextContentBlock> for PollQuestion {
|
||||
pub enum PollKind {
|
||||
/// The results are revealed once the poll is closed.
|
||||
#[default]
|
||||
#[ruma_enum(rename = "org.matrix.msc3381.poll.undisclosed", alias = "m.poll.undisclosed")]
|
||||
#[ruma_enum(rename = "org.matrix.msc3381.v2.undisclosed")]
|
||||
Undisclosed,
|
||||
|
||||
/// The votes are visible up until and including when the poll is closed.
|
||||
#[ruma_enum(rename = "org.matrix.msc3381.poll.disclosed", alias = "m.poll.disclosed")]
|
||||
#[ruma_enum(rename = "org.matrix.msc3381.v2.disclosed")]
|
||||
Disclosed,
|
||||
|
||||
#[doc(hidden)]
|
||||
@ -129,11 +153,6 @@ impl PollAnswers {
|
||||
|
||||
/// The largest number of values contained in a `PollAnswers`.
|
||||
pub const MAX_LENGTH: usize = 20;
|
||||
|
||||
/// The answers of this `PollAnswers`.
|
||||
pub fn answers(&self) -> &[PollAnswer] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// An error encountered when trying to convert to a `PollAnswers`.
|
||||
@ -170,6 +189,14 @@ impl TryFrom<&[PollAnswer]> for PollAnswers {
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for PollAnswers {
|
||||
type Target = [PollAnswer];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Poll answer.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
@ -177,6 +204,7 @@ pub struct PollAnswer {
|
||||
/// The ID of the answer.
|
||||
///
|
||||
/// This must be unique among the answers of a poll.
|
||||
#[serde(rename = "org.matrix.msc3381.v2.id")]
|
||||
pub id: String,
|
||||
|
||||
/// The text representation of the answer.
|
||||
|
@ -1,17 +1,18 @@
|
||||
#![cfg(feature = "unstable-msc3381")]
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use assert_matches::assert_matches;
|
||||
use assign::assign;
|
||||
use js_int::uint;
|
||||
use ruma_common::{
|
||||
event_id,
|
||||
events::{
|
||||
message::TextContentBlock,
|
||||
poll::{
|
||||
end::{PollEndContent, PollEndEventContent},
|
||||
response::{PollResponseContent, PollResponseEventContent},
|
||||
end::PollEndEventContent,
|
||||
response::PollResponseEventContent,
|
||||
start::{
|
||||
PollAnswer, PollAnswers, PollAnswersError, PollKind, PollStartContent,
|
||||
PollAnswer, PollAnswers, PollAnswersError, PollContentBlock, PollKind,
|
||||
PollStartEventContent,
|
||||
},
|
||||
},
|
||||
@ -24,43 +25,43 @@ use serde_json::{from_value as from_json_value, json, to_value as to_json_value}
|
||||
#[test]
|
||||
fn poll_answers_deserialization_valid() {
|
||||
let json_data = json!([
|
||||
{ "id": "aaa", "org.matrix.msc1767.text": [{ "body": "First answer" }] },
|
||||
{ "id": "bbb", "org.matrix.msc1767.text": [{ "body": "Second answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "aaa", "org.matrix.msc1767.text": [{ "body": "First answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "bbb", "org.matrix.msc1767.text": [{ "body": "Second answer" }] },
|
||||
]);
|
||||
|
||||
let answers = from_json_value::<PollAnswers>(json_data).unwrap();
|
||||
assert_eq!(answers.answers().len(), 2);
|
||||
assert_eq!(answers.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn poll_answers_deserialization_truncate() {
|
||||
let json_data = json!([
|
||||
{ "id": "aaa", "org.matrix.msc1767.text": [{ "body": "1st answer" }] },
|
||||
{ "id": "bbb", "org.matrix.msc1767.text": [{ "body": "2nd answer" }] },
|
||||
{ "id": "ccc", "org.matrix.msc1767.text": [{ "body": "3rd answer" }] },
|
||||
{ "id": "ddd", "org.matrix.msc1767.text": [{ "body": "4th answer" }] },
|
||||
{ "id": "eee", "org.matrix.msc1767.text": [{ "body": "5th answer" }] },
|
||||
{ "id": "fff", "org.matrix.msc1767.text": [{ "body": "6th answer" }] },
|
||||
{ "id": "ggg", "org.matrix.msc1767.text": [{ "body": "7th answer" }] },
|
||||
{ "id": "hhh", "org.matrix.msc1767.text": [{ "body": "8th answer" }] },
|
||||
{ "id": "iii", "org.matrix.msc1767.text": [{ "body": "9th answer" }] },
|
||||
{ "id": "jjj", "org.matrix.msc1767.text": [{ "body": "10th answer" }] },
|
||||
{ "id": "kkk", "org.matrix.msc1767.text": [{ "body": "11th answer" }] },
|
||||
{ "id": "lll", "org.matrix.msc1767.text": [{ "body": "12th answer" }] },
|
||||
{ "id": "mmm", "org.matrix.msc1767.text": [{ "body": "13th answer" }] },
|
||||
{ "id": "nnn", "org.matrix.msc1767.text": [{ "body": "14th answer" }] },
|
||||
{ "id": "ooo", "org.matrix.msc1767.text": [{ "body": "15th answer" }] },
|
||||
{ "id": "ppp", "org.matrix.msc1767.text": [{ "body": "16th answer" }] },
|
||||
{ "id": "qqq", "org.matrix.msc1767.text": [{ "body": "17th answer" }] },
|
||||
{ "id": "rrr", "org.matrix.msc1767.text": [{ "body": "18th answer" }] },
|
||||
{ "id": "sss", "org.matrix.msc1767.text": [{ "body": "19th answer" }] },
|
||||
{ "id": "ttt", "org.matrix.msc1767.text": [{ "body": "20th answer" }] },
|
||||
{ "id": "uuu", "org.matrix.msc1767.text": [{ "body": "21th answer" }] },
|
||||
{ "id": "vvv", "org.matrix.msc1767.text": [{ "body": "22th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "aaa", "org.matrix.msc1767.text": [{ "body": "1st answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "bbb", "org.matrix.msc1767.text": [{ "body": "2nd answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "ccc", "org.matrix.msc1767.text": [{ "body": "3rd answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "ddd", "org.matrix.msc1767.text": [{ "body": "4th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "eee", "org.matrix.msc1767.text": [{ "body": "5th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "fff", "org.matrix.msc1767.text": [{ "body": "6th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "ggg", "org.matrix.msc1767.text": [{ "body": "7th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "hhh", "org.matrix.msc1767.text": [{ "body": "8th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "iii", "org.matrix.msc1767.text": [{ "body": "9th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "jjj", "org.matrix.msc1767.text": [{ "body": "10th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "kkk", "org.matrix.msc1767.text": [{ "body": "11th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "lll", "org.matrix.msc1767.text": [{ "body": "12th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "mmm", "org.matrix.msc1767.text": [{ "body": "13th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "nnn", "org.matrix.msc1767.text": [{ "body": "14th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "ooo", "org.matrix.msc1767.text": [{ "body": "15th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "ppp", "org.matrix.msc1767.text": [{ "body": "16th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "qqq", "org.matrix.msc1767.text": [{ "body": "17th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "rrr", "org.matrix.msc1767.text": [{ "body": "18th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "sss", "org.matrix.msc1767.text": [{ "body": "19th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "ttt", "org.matrix.msc1767.text": [{ "body": "20th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "uuu", "org.matrix.msc1767.text": [{ "body": "21th answer" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "vvv", "org.matrix.msc1767.text": [{ "body": "22th answer" }] },
|
||||
]);
|
||||
|
||||
let answers = from_json_value::<PollAnswers>(json_data).unwrap();
|
||||
assert_eq!(answers.answers().len(), 20);
|
||||
assert_eq!(answers.len(), 20);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -74,40 +75,10 @@ fn poll_answers_deserialization_not_enough() {
|
||||
|
||||
#[test]
|
||||
fn start_content_serialization() {
|
||||
let event_content = PollStartEventContent::new(PollStartContent::new(
|
||||
let event_content = PollStartEventContent::with_plain_text(
|
||||
"How's the weather?\n1. Not bad…\n2. Fine.\n3. Amazing!",
|
||||
PollContentBlock::new(
|
||||
TextContentBlock::plain("How's the weather?"),
|
||||
PollKind::Undisclosed,
|
||||
vec![
|
||||
PollAnswer::new("not-bad".to_owned(), TextContentBlock::plain("Not bad…")),
|
||||
PollAnswer::new("fine".to_owned(), TextContentBlock::plain("Fine.")),
|
||||
PollAnswer::new("amazing".to_owned(), TextContentBlock::plain("Amazing!")),
|
||||
]
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
));
|
||||
|
||||
assert_eq!(
|
||||
to_json_value(&event_content).unwrap(),
|
||||
json!({
|
||||
"org.matrix.msc3381.poll.start": {
|
||||
"question": { "org.matrix.msc1767.text": [{ "body": "How's the weather?" }] },
|
||||
"kind": "org.matrix.msc3381.poll.undisclosed",
|
||||
"answers": [
|
||||
{ "id": "not-bad", "org.matrix.msc1767.text": [{ "body": "Not bad…" }] },
|
||||
{ "id": "fine", "org.matrix.msc1767.text": [{ "body": "Fine." }] },
|
||||
{ "id": "amazing", "org.matrix.msc1767.text": [{ "body": "Amazing!" }] },
|
||||
],
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn start_event_serialization() {
|
||||
let content = PollStartEventContent::new(assign!(
|
||||
PollStartContent::new(
|
||||
TextContentBlock::plain("How's the weather?"),
|
||||
PollKind::Disclosed,
|
||||
vec![
|
||||
PollAnswer::new("not-bad".to_owned(), TextContentBlock::plain("Not bad…")),
|
||||
PollAnswer::new("fine".to_owned(), TextContentBlock::plain("Fine.")),
|
||||
@ -116,20 +87,59 @@ fn start_event_serialization() {
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
),
|
||||
{ max_selections: uint!(2) }
|
||||
));
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
to_json_value(&event_content).unwrap(),
|
||||
json!({
|
||||
"org.matrix.msc1767.text": [
|
||||
{ "body": "How's the weather?\n1. Not bad…\n2. Fine.\n3. Amazing!" }
|
||||
],
|
||||
"org.matrix.msc3381.v2.poll": {
|
||||
"question": { "org.matrix.msc1767.text": [{ "body": "How's the weather?" }] },
|
||||
"answers": [
|
||||
{ "org.matrix.msc3381.v2.id": "not-bad", "org.matrix.msc1767.text": [{ "body": "Not bad…" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "fine", "org.matrix.msc1767.text": [{ "body": "Fine." }] },
|
||||
{ "org.matrix.msc3381.v2.id": "amazing", "org.matrix.msc1767.text": [{ "body": "Amazing!" }] },
|
||||
],
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn start_event_serialization() {
|
||||
let mut poll = PollContentBlock::new(
|
||||
TextContentBlock::plain("How's the weather?"),
|
||||
vec![
|
||||
PollAnswer::new("not-bad".to_owned(), TextContentBlock::plain("Not bad…")),
|
||||
PollAnswer::new("fine".to_owned(), TextContentBlock::plain("Fine.")),
|
||||
PollAnswer::new("amazing".to_owned(), TextContentBlock::plain("Amazing!")),
|
||||
]
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
);
|
||||
poll.kind = PollKind::Disclosed;
|
||||
poll.max_selections = uint!(2);
|
||||
let content = PollStartEventContent::with_plain_text(
|
||||
"How's the weather?\n1. Not bad…\n2. Fine.\n3. Amazing!",
|
||||
poll,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
to_json_value(&content).unwrap(),
|
||||
json!({
|
||||
"org.matrix.msc3381.poll.start": {
|
||||
"org.matrix.msc1767.text": [
|
||||
{ "body": "How's the weather?\n1. Not bad…\n2. Fine.\n3. Amazing!" }
|
||||
],
|
||||
"org.matrix.msc3381.v2.poll": {
|
||||
"question": { "org.matrix.msc1767.text": [{ "body": "How's the weather?" }] },
|
||||
"kind": "org.matrix.msc3381.poll.disclosed",
|
||||
"kind": "org.matrix.msc3381.v2.disclosed",
|
||||
"max_selections": 2,
|
||||
"answers": [
|
||||
{ "id": "not-bad", "org.matrix.msc1767.text": [{ "body": "Not bad…" }] },
|
||||
{ "id": "fine", "org.matrix.msc1767.text": [{ "body": "Fine." }] },
|
||||
{ "id": "amazing", "org.matrix.msc1767.text": [{ "body": "Amazing!" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "not-bad", "org.matrix.msc1767.text": [{ "body": "Not bad…" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "fine", "org.matrix.msc1767.text": [{ "body": "Fine." }] },
|
||||
{ "org.matrix.msc3381.v2.id": "amazing", "org.matrix.msc1767.text": [{ "body": "Amazing!" }] },
|
||||
]
|
||||
},
|
||||
})
|
||||
@ -140,14 +150,16 @@ fn start_event_serialization() {
|
||||
fn start_event_deserialization() {
|
||||
let json_data = json!({
|
||||
"content": {
|
||||
"org.matrix.msc3381.poll.start": {
|
||||
"org.matrix.msc1767.text": [
|
||||
{ "body": "How's the weather?\n1. Not bad…\n2. Fine.\n3. Amazing!" }
|
||||
],
|
||||
"org.matrix.msc3381.v2.poll": {
|
||||
"question": { "org.matrix.msc1767.text": [{ "body": "How's the weather?" }] },
|
||||
"kind": "org.matrix.msc3381.poll.undisclosed",
|
||||
"max_selections": 2,
|
||||
"answers": [
|
||||
{ "id": "not-bad", "org.matrix.msc1767.text": [{ "body": "Not bad…" }] },
|
||||
{ "id": "fine", "org.matrix.msc1767.text": [{ "body": "Fine." }] },
|
||||
{ "id": "amazing", "org.matrix.msc1767.text": [{ "body": "Amazing!" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "not-bad", "org.matrix.msc1767.text": [{ "body": "Not bad…" }] },
|
||||
{ "org.matrix.msc3381.v2.id": "fine", "org.matrix.msc1767.text": [{ "body": "Fine." }] },
|
||||
{ "org.matrix.msc3381.v2.id": "amazing", "org.matrix.msc1767.text": [{ "body": "Amazing!" }] },
|
||||
]
|
||||
},
|
||||
},
|
||||
@ -155,7 +167,7 @@ fn start_event_deserialization() {
|
||||
"origin_server_ts": 134_829_848,
|
||||
"room_id": "!roomid:notareal.hs",
|
||||
"sender": "@user:notareal.hs",
|
||||
"type": "org.matrix.msc3381.poll.start",
|
||||
"type": "org.matrix.msc3381.v2.poll.start",
|
||||
});
|
||||
|
||||
let event = from_json_value::<AnyMessageLikeEvent>(json_data).unwrap();
|
||||
@ -163,11 +175,15 @@ fn start_event_deserialization() {
|
||||
event,
|
||||
AnyMessageLikeEvent::PollStart(MessageLikeEvent::Original(message_event)) => message_event
|
||||
);
|
||||
let poll_start = message_event.content.poll_start;
|
||||
assert_eq!(poll_start.question.text[0].body, "How's the weather?");
|
||||
assert_eq!(poll_start.kind, PollKind::Undisclosed);
|
||||
assert_eq!(poll_start.max_selections, uint!(2));
|
||||
let answers = poll_start.answers.answers();
|
||||
assert_eq!(
|
||||
message_event.content.text[0].body,
|
||||
"How's the weather?\n1. Not bad…\n2. Fine.\n3. Amazing!"
|
||||
);
|
||||
let poll = message_event.content.poll;
|
||||
assert_eq!(poll.question.text[0].body, "How's the weather?");
|
||||
assert_eq!(poll.kind, PollKind::Undisclosed);
|
||||
assert_eq!(poll.max_selections, uint!(2));
|
||||
let answers = poll.answers;
|
||||
assert_eq!(answers.len(), 3);
|
||||
assert_eq!(answers[0].id, "not-bad");
|
||||
assert_eq!(answers[0].text[0].body, "Not bad…");
|
||||
@ -180,16 +196,14 @@ fn start_event_deserialization() {
|
||||
#[test]
|
||||
fn response_content_serialization() {
|
||||
let event_content = PollResponseEventContent::new(
|
||||
PollResponseContent::new(vec!["my-answer".to_owned()]),
|
||||
vec!["my-answer".to_owned()].into(),
|
||||
event_id!("$related_event:notareal.hs").to_owned(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
to_json_value(&event_content).unwrap(),
|
||||
json!({
|
||||
"org.matrix.msc3381.poll.response": {
|
||||
"answers": ["my-answer"],
|
||||
},
|
||||
"org.matrix.msc3381.v2.selections": ["my-answer"],
|
||||
"m.relates_to": {
|
||||
"rel_type": "m.reference",
|
||||
"event_id": "$related_event:notareal.hs",
|
||||
@ -201,16 +215,14 @@ fn response_content_serialization() {
|
||||
#[test]
|
||||
fn response_event_serialization() {
|
||||
let content = PollResponseEventContent::new(
|
||||
PollResponseContent::new(vec!["first-answer".to_owned(), "second-answer".to_owned()]),
|
||||
vec!["first-answer".to_owned(), "second-answer".to_owned()].into(),
|
||||
event_id!("$related_event:notareal.hs").to_owned(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
to_json_value(&content).unwrap(),
|
||||
json!({
|
||||
"org.matrix.msc3381.poll.response": {
|
||||
"answers": ["first-answer", "second-answer"],
|
||||
},
|
||||
"org.matrix.msc3381.v2.selections": ["first-answer", "second-answer"],
|
||||
"m.relates_to": {
|
||||
"rel_type": "m.reference",
|
||||
"event_id": "$related_event:notareal.hs",
|
||||
@ -220,12 +232,10 @@ fn response_event_serialization() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn response_event_unstable_deserialization() {
|
||||
fn response_event_deserialization() {
|
||||
let json_data = json!({
|
||||
"content": {
|
||||
"org.matrix.msc3381.poll.response": {
|
||||
"answers": ["my-answer"],
|
||||
},
|
||||
"org.matrix.msc3381.v2.selections": ["my-answer"],
|
||||
"m.relates_to": {
|
||||
"rel_type": "m.reference",
|
||||
"event_id": "$related_event:notareal.hs",
|
||||
@ -235,7 +245,7 @@ fn response_event_unstable_deserialization() {
|
||||
"origin_server_ts": 134_829_848,
|
||||
"room_id": "!roomid:notareal.hs",
|
||||
"sender": "@user:notareal.hs",
|
||||
"type": "org.matrix.msc3381.poll.response",
|
||||
"type": "org.matrix.msc3381.v2.poll.response",
|
||||
});
|
||||
|
||||
let event = from_json_value::<AnyMessageLikeEvent>(json_data).unwrap();
|
||||
@ -244,45 +254,9 @@ fn response_event_unstable_deserialization() {
|
||||
AnyMessageLikeEvent::PollResponse(MessageLikeEvent::Original(message_event))
|
||||
=> message_event
|
||||
);
|
||||
let answers = message_event.content.poll_response.answers;
|
||||
assert_eq!(answers.len(), 1);
|
||||
assert_eq!(answers[0], "my-answer");
|
||||
let event_id = assert_matches!(
|
||||
message_event.content.relates_to,
|
||||
Reference { event_id, .. } => event_id
|
||||
);
|
||||
assert_eq!(event_id, "$related_event:notareal.hs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn response_event_stable_deserialization() {
|
||||
let json_data = json!({
|
||||
"content": {
|
||||
"m.poll.response": {
|
||||
"answers": ["first-answer", "second-answer"],
|
||||
},
|
||||
"m.relates_to": {
|
||||
"rel_type": "m.reference",
|
||||
"event_id": "$related_event:notareal.hs",
|
||||
}
|
||||
},
|
||||
"event_id": "$event:notareal.hs",
|
||||
"origin_server_ts": 134_829_848,
|
||||
"room_id": "!roomid:notareal.hs",
|
||||
"sender": "@user:notareal.hs",
|
||||
"type": "m.poll.response",
|
||||
});
|
||||
|
||||
let event = from_json_value::<AnyMessageLikeEvent>(json_data).unwrap();
|
||||
let message_event = assert_matches!(
|
||||
event,
|
||||
AnyMessageLikeEvent::PollResponse(MessageLikeEvent::Original(message_event))
|
||||
=> message_event
|
||||
);
|
||||
let answers = message_event.content.poll_response.answers;
|
||||
assert_eq!(answers.len(), 2);
|
||||
assert_eq!(answers[0], "first-answer");
|
||||
assert_eq!(answers[1], "second-answer");
|
||||
let selections = message_event.content.selections;
|
||||
assert_eq!(selections.len(), 1);
|
||||
assert_eq!(selections[0], "my-answer");
|
||||
let event_id = assert_matches!(
|
||||
message_event.content.relates_to,
|
||||
Reference { event_id, .. } => event_id
|
||||
@ -292,15 +266,17 @@ fn response_event_stable_deserialization() {
|
||||
|
||||
#[test]
|
||||
fn end_content_serialization() {
|
||||
let event_content = PollEndEventContent::new(
|
||||
PollEndContent::new(),
|
||||
let event_content = PollEndEventContent::with_plain_text(
|
||||
"The poll has closed. Top answer: Amazing!",
|
||||
event_id!("$related_event:notareal.hs").to_owned(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
to_json_value(&event_content).unwrap(),
|
||||
json!({
|
||||
"org.matrix.msc3381.poll.end": {},
|
||||
"org.matrix.msc1767.text": [
|
||||
{ "body": "The poll has closed. Top answer: Amazing!" }
|
||||
],
|
||||
"m.relates_to": {
|
||||
"rel_type": "m.reference",
|
||||
"event_id": "$related_event:notareal.hs",
|
||||
@ -311,15 +287,30 @@ fn end_content_serialization() {
|
||||
|
||||
#[test]
|
||||
fn end_event_serialization() {
|
||||
let content = PollEndEventContent::new(
|
||||
PollEndContent::new(),
|
||||
let mut content = PollEndEventContent::with_plain_text(
|
||||
"The poll has closed. Top answer: Amazing!",
|
||||
event_id!("$related_event:notareal.hs").to_owned(),
|
||||
);
|
||||
content.poll_results = Some(
|
||||
BTreeMap::from([
|
||||
("not-bad".to_owned(), uint!(1)),
|
||||
("fine".to_owned(), uint!(5)),
|
||||
("amazing".to_owned(), uint!(14)),
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
to_json_value(&content).unwrap(),
|
||||
json!({
|
||||
"org.matrix.msc3381.poll.end": {},
|
||||
"org.matrix.msc1767.text": [
|
||||
{ "body": "The poll has closed. Top answer: Amazing!" },
|
||||
],
|
||||
"org.matrix.msc3381.v2.poll.results": {
|
||||
"not-bad": 1,
|
||||
"fine": 5,
|
||||
"amazing": 14,
|
||||
},
|
||||
"m.relates_to": {
|
||||
"rel_type": "m.reference",
|
||||
"event_id": "$related_event:notareal.hs",
|
||||
@ -329,10 +320,12 @@ fn end_event_serialization() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn end_event_unstable_deserialization() {
|
||||
fn end_event_deserialization() {
|
||||
let json_data = json!({
|
||||
"content": {
|
||||
"org.matrix.msc3381.poll.end": {},
|
||||
"org.matrix.msc1767.text": [
|
||||
{ "body": "The poll has closed. Top answer: Amazing!" },
|
||||
],
|
||||
"m.relates_to": {
|
||||
"rel_type": "m.reference",
|
||||
"event_id": "$related_event:notareal.hs",
|
||||
@ -342,36 +335,7 @@ fn end_event_unstable_deserialization() {
|
||||
"origin_server_ts": 134_829_848,
|
||||
"room_id": "!roomid:notareal.hs",
|
||||
"sender": "@user:notareal.hs",
|
||||
"type": "org.matrix.msc3381.poll.end",
|
||||
});
|
||||
|
||||
let event = from_json_value::<AnyMessageLikeEvent>(json_data).unwrap();
|
||||
let message_event = assert_matches!(
|
||||
event,
|
||||
AnyMessageLikeEvent::PollEnd(MessageLikeEvent::Original(message_event)) => message_event
|
||||
);
|
||||
let event_id = assert_matches!(
|
||||
message_event.content.relates_to,
|
||||
Reference { event_id, .. } => event_id
|
||||
);
|
||||
assert_eq!(event_id, "$related_event:notareal.hs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn end_event_stable_deserialization() {
|
||||
let json_data = json!({
|
||||
"content": {
|
||||
"m.poll.end": {},
|
||||
"m.relates_to": {
|
||||
"rel_type": "m.reference",
|
||||
"event_id": "$related_event:notareal.hs",
|
||||
}
|
||||
},
|
||||
"event_id": "$event:notareal.hs",
|
||||
"origin_server_ts": 134_829_848,
|
||||
"room_id": "!roomid:notareal.hs",
|
||||
"sender": "@user:notareal.hs",
|
||||
"type": "m.poll.end",
|
||||
"type": "org.matrix.msc3381.v2.poll.end",
|
||||
});
|
||||
|
||||
let event = from_json_value::<AnyMessageLikeEvent>(json_data).unwrap();
|
||||
@ -379,6 +343,7 @@ fn end_event_stable_deserialization() {
|
||||
event,
|
||||
AnyMessageLikeEvent::PollEnd(MessageLikeEvent::Original(message_event)) => message_event
|
||||
);
|
||||
assert_eq!(message_event.content.text[0].body, "The poll has closed. Top answer: Amazing!");
|
||||
let event_id = assert_matches!(
|
||||
message_event.content.relates_to,
|
||||
Reference { event_id, .. } => event_id
|
||||
|
Loading…
x
Reference in New Issue
Block a user