mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 14:35:36 +01:00
Merge pull request #1134 from syrtcevvi/fix/more-rusty-api
Add `MaybeAnonymousUser` type
This commit is contained in:
commit
ae83ff15a2
8 changed files with 253 additions and 58 deletions
23
Cargo.lock
generated
23
Cargo.lock
generated
|
@ -441,6 +441,12 @@ dependencies = [
|
||||||
"syn 2.0.52",
|
"syn 2.0.52",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "diff"
|
||||||
|
version = "0.1.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.10.7"
|
version = "0.10.7"
|
||||||
|
@ -1395,6 +1401,16 @@ dependencies = [
|
||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pretty_assertions"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66"
|
||||||
|
dependencies = [
|
||||||
|
"diff",
|
||||||
|
"yansi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pretty_env_logger"
|
name = "pretty_env_logger"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
@ -2216,6 +2232,7 @@ dependencies = [
|
||||||
"mime",
|
"mime",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
|
"pretty_assertions",
|
||||||
"pretty_env_logger",
|
"pretty_env_logger",
|
||||||
"rc-box",
|
"rc-box",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
@ -2875,6 +2892,12 @@ version = "0.2.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9d422e8e38ec76e2f06ee439ccc765e9c6a9638b9e7c9f2e8255e4d41e8bd852"
|
checksum = "9d422e8e38ec76e2f06ee439ccc765e9c6a9638b9e7c9f2e8255e4d41e8bd852"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yansi"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.7.35"
|
version = "0.7.35"
|
||||||
|
|
|
@ -21,6 +21,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
[pr1131]: https://github.com/teloxide/teloxide/pull/1131
|
[pr1131]: https://github.com/teloxide/teloxide/pull/1131
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- `MaybeAnonymousUser` type introduced, which replaced `PollAnswer::voter: Voter` and `MessageReactionUpdated::{user, actor_chat}` in `MessageReactionUpdated`([#1134][pr1134])
|
||||||
|
|
||||||
|
[pr1134]: https://github.com/teloxide/teloxide/pull/1134
|
||||||
|
|
||||||
## 0.10.1 - 2024-08-17
|
## 0.10.1 - 2024-08-17
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -95,6 +95,7 @@ ron = "0.7"
|
||||||
indexmap = { version = "1.9", features = ["serde-1"] }
|
indexmap = { version = "1.9", features = ["serde-1"] }
|
||||||
aho-corasick = "0.7"
|
aho-corasick = "0.7"
|
||||||
itertools = "0.10"
|
itertools = "0.10"
|
||||||
|
pretty_assertions = "1.4.0"
|
||||||
|
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
|
|
|
@ -91,6 +91,7 @@ pub use link_preview_options::*;
|
||||||
pub use location::*;
|
pub use location::*;
|
||||||
pub use login_url::*;
|
pub use login_url::*;
|
||||||
pub use mask_position::*;
|
pub use mask_position::*;
|
||||||
|
pub use maybe_anonymous_user::*;
|
||||||
pub use maybe_inaccessible_message::*;
|
pub use maybe_inaccessible_message::*;
|
||||||
pub use me::*;
|
pub use me::*;
|
||||||
pub use menu_button::*;
|
pub use menu_button::*;
|
||||||
|
@ -218,6 +219,7 @@ mod link_preview_options;
|
||||||
mod location;
|
mod location;
|
||||||
mod login_url;
|
mod login_url;
|
||||||
mod mask_position;
|
mod mask_position;
|
||||||
|
mod maybe_anonymous_user;
|
||||||
mod maybe_inaccessible_message;
|
mod maybe_inaccessible_message;
|
||||||
mod me;
|
mod me;
|
||||||
mod menu_button;
|
mod menu_button;
|
||||||
|
|
69
crates/teloxide-core/src/types/maybe_anonymous_user.rs
Normal file
69
crates/teloxide-core/src/types/maybe_anonymous_user.rs
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::types::{Chat, User};
|
||||||
|
|
||||||
|
/// Represents either [`User`] or anonymous user ([`Chat`]) that acts on behalf
|
||||||
|
/// of the chat
|
||||||
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum MaybeAnonymousUser {
|
||||||
|
User(User),
|
||||||
|
Chat(Chat),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MaybeAnonymousUser {
|
||||||
|
pub fn is_user(&self) -> bool {
|
||||||
|
self.user().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_chat(&self) -> bool {
|
||||||
|
self.chat().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn chat(&self) -> Option<&Chat> {
|
||||||
|
match self {
|
||||||
|
Self::Chat(chat) => Some(chat),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn user(&self) -> Option<&User> {
|
||||||
|
match self {
|
||||||
|
Self::User(user) => Some(user),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn user_de() {
|
||||||
|
let json = r#"{
|
||||||
|
"id": 42,
|
||||||
|
"is_bot": false,
|
||||||
|
"first_name": "blah"
|
||||||
|
}"#;
|
||||||
|
|
||||||
|
let user: MaybeAnonymousUser = serde_json::from_str(json).unwrap();
|
||||||
|
|
||||||
|
assert!(user.user().is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn chat_de() {
|
||||||
|
let json = r#"{
|
||||||
|
"id": -1001160242915,
|
||||||
|
"title": "a",
|
||||||
|
"type": "group"
|
||||||
|
}"#;
|
||||||
|
|
||||||
|
let chat: MaybeAnonymousUser = serde_json::from_str(json).unwrap();
|
||||||
|
|
||||||
|
assert!(chat.chat().is_some());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
|
|
||||||
use crate::types::{Chat, MessageId, ReactionType, User};
|
use crate::types::{Chat, MaybeAnonymousUser, MessageId, ReactionType, User};
|
||||||
|
|
||||||
/// This object represents a change of a reaction on a message performed by a
|
/// This object represents a change of a reaction on a message performed by a
|
||||||
/// user.
|
/// user.
|
||||||
|
@ -15,12 +15,11 @@ pub struct MessageReactionUpdated {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub message_id: MessageId,
|
pub message_id: MessageId,
|
||||||
|
|
||||||
/// The user that changed the reaction, if the user isn't anonymous
|
/// The [`MaybeAnonymousUser::User`] that changed the reaction, if the user
|
||||||
pub user: Option<User>,
|
/// isn't anonymous or the [`MaybeAnonymousUser::Chat`] on behalf of
|
||||||
|
/// which the reaction was changed, if the user is anonymous
|
||||||
/// The chat on behalf of which the reaction was changed, if the user is
|
#[serde(deserialize_with = "deserialize_actor", flatten)]
|
||||||
/// anonymous
|
pub actor: MaybeAnonymousUser,
|
||||||
pub actor_chat: Option<Chat>,
|
|
||||||
|
|
||||||
/// Date of the change in Unix time
|
/// Date of the change in Unix time
|
||||||
#[serde(with = "crate::types::serde_date_from_unix_timestamp")]
|
#[serde(with = "crate::types::serde_date_from_unix_timestamp")]
|
||||||
|
@ -35,22 +34,37 @@ pub struct MessageReactionUpdated {
|
||||||
|
|
||||||
impl MessageReactionUpdated {
|
impl MessageReactionUpdated {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn actor_chat(&self) -> Option<&Chat> {
|
pub fn chat(&self) -> Option<&Chat> {
|
||||||
self.actor_chat.as_ref()
|
self.actor.chat()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn user(&self) -> Option<&User> {
|
pub fn user(&self) -> Option<&User> {
|
||||||
self.user.as_ref()
|
self.actor.user()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct ActorDe {
|
||||||
|
/// The user that changed the reaction, if the user isn't anonymous
|
||||||
|
user: Option<User>,
|
||||||
|
/// The chat on behalf of which the reaction was changed, if the user is
|
||||||
|
/// anonymous
|
||||||
|
actor_chat: Option<Chat>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize_actor<'d, D: Deserializer<'d>>(d: D) -> Result<MaybeAnonymousUser, D::Error> {
|
||||||
|
let ActorDe { user, actor_chat } = ActorDe::deserialize(d)?;
|
||||||
|
|
||||||
|
Ok(actor_chat.map(MaybeAnonymousUser::Chat).or(user.map(MaybeAnonymousUser::User)).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn deserialize() {
|
fn deserialize_user() {
|
||||||
let data = r#"
|
let data = r#"
|
||||||
{
|
{
|
||||||
"chat": {
|
"chat": {
|
||||||
|
@ -77,6 +91,37 @@ mod tests {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
serde_json::from_str::<MessageReactionUpdated>(data).unwrap();
|
let message_reaction_update = serde_json::from_str::<MessageReactionUpdated>(data).unwrap();
|
||||||
|
|
||||||
|
assert!(message_reaction_update.actor.is_user());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deserialize_chat() {
|
||||||
|
let data = r#"{
|
||||||
|
"chat": {
|
||||||
|
"id": -1002199793788,
|
||||||
|
"title": "тест",
|
||||||
|
"type": "supergroup"
|
||||||
|
},
|
||||||
|
"message_id": 2,
|
||||||
|
"actor_chat": {
|
||||||
|
"id": -1002199793788,
|
||||||
|
"title": "тест",
|
||||||
|
"type": "supergroup"
|
||||||
|
},
|
||||||
|
"date": 1723798597,
|
||||||
|
"old_reaction": [
|
||||||
|
{
|
||||||
|
"type": "emoji",
|
||||||
|
"emoji": "❤"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"new_reaction": []
|
||||||
|
}"#;
|
||||||
|
|
||||||
|
let message_reaction_update = serde_json::from_str::<MessageReactionUpdated>(data).unwrap();
|
||||||
|
|
||||||
|
assert!(message_reaction_update.actor.is_chat())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
use serde::{Deserialize, Deserializer, Serialize};
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
|
|
||||||
use crate::types::{Chat, User};
|
use crate::types::{Chat, MaybeAnonymousUser, User};
|
||||||
|
|
||||||
#[serde_with::skip_serializing_none]
|
#[serde_with::skip_serializing_none]
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct PollAnswer {
|
pub struct PollAnswer {
|
||||||
|
// FIXME: PollId
|
||||||
/// Unique poll identifier.
|
/// Unique poll identifier.
|
||||||
pub poll_id: String,
|
pub poll_id: String,
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@ pub struct PollAnswer {
|
||||||
/// If the voter isn't anonymous, stores the user that changed
|
/// If the voter isn't anonymous, stores the user that changed
|
||||||
/// the answer to the poll
|
/// the answer to the poll
|
||||||
#[serde(deserialize_with = "deserialize_voter", flatten)]
|
#[serde(deserialize_with = "deserialize_voter", flatten)]
|
||||||
pub voter: Voter,
|
pub voter: MaybeAnonymousUser,
|
||||||
|
|
||||||
/// 0-based identifiers of answer options, chosen by the user.
|
/// 0-based identifiers of answer options, chosen by the user.
|
||||||
///
|
///
|
||||||
|
@ -22,31 +23,6 @@ pub struct PollAnswer {
|
||||||
pub option_ids: Vec<u8>,
|
pub option_ids: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum Voter {
|
|
||||||
Chat(Chat),
|
|
||||||
User(User),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Voter {
|
|
||||||
#[must_use]
|
|
||||||
pub fn chat(&self) -> Option<&Chat> {
|
|
||||||
match self {
|
|
||||||
Self::Chat(chat) => Some(chat),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn user(&self) -> Option<&User> {
|
|
||||||
match self {
|
|
||||||
Self::User(user) => Some(user),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// These fields `chat` and `user` from the original [`PollAnswer`] should be
|
/// These fields `chat` and `user` from the original [`PollAnswer`] should be
|
||||||
/// exclusive, but in cases when the `voter_chat` is presented the `user` isn't
|
/// exclusive, but in cases when the `voter_chat` is presented the `user` isn't
|
||||||
/// `None`, but rather actual value for backward compatibility, the field `user`
|
/// `None`, but rather actual value for backward compatibility, the field `user`
|
||||||
|
@ -61,9 +37,9 @@ struct VoterDe {
|
||||||
pub user: Option<User>,
|
pub user: Option<User>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_voter<'d, D: Deserializer<'d>>(d: D) -> Result<Voter, D::Error> {
|
fn deserialize_voter<'d, D: Deserializer<'d>>(d: D) -> Result<MaybeAnonymousUser, D::Error> {
|
||||||
let VoterDe { voter_chat, user } = VoterDe::deserialize(d)?;
|
let VoterDe { voter_chat, user } = VoterDe::deserialize(d)?;
|
||||||
Ok(voter_chat.map(Voter::Chat).or(user.map(Voter::User)).unwrap())
|
Ok(voter_chat.map(MaybeAnonymousUser::Chat).or(user.map(MaybeAnonymousUser::User)).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -71,21 +47,22 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_poll_answer_with_user_de() {
|
fn poll_answer_with_user_de() {
|
||||||
let json = r#"{
|
let json = r#"{
|
||||||
"poll_id":"POLL_ID",
|
"poll_id": "POLL_ID",
|
||||||
"user": {"id":42,"is_bot":false,"first_name":"blah"},
|
"user": {"id": 42,"is_bot": false,"first_name": "blah"},
|
||||||
"option_ids": []
|
"option_ids": []
|
||||||
}"#;
|
}"#;
|
||||||
|
|
||||||
let poll_answer: PollAnswer = serde_json::from_str(json).unwrap();
|
let poll_answer: PollAnswer = serde_json::from_str(json).unwrap();
|
||||||
assert!(matches!(poll_answer.voter, Voter::User(_)));
|
|
||||||
|
assert!(poll_answer.voter.is_user());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_poll_answer_with_voter_chat_de() {
|
fn poll_answer_with_voter_chat_de() {
|
||||||
let json = r#"{
|
let json = r#"{
|
||||||
"poll_id":"POLL_ID",
|
"poll_id": "POLL_ID",
|
||||||
"voter_chat": {
|
"voter_chat": {
|
||||||
"id": -1001160242915,
|
"id": -1001160242915,
|
||||||
"title": "a",
|
"title": "a",
|
||||||
|
@ -95,11 +72,11 @@ mod tests {
|
||||||
}"#;
|
}"#;
|
||||||
|
|
||||||
let poll_answer: PollAnswer = serde_json::from_str(json).unwrap();
|
let poll_answer: PollAnswer = serde_json::from_str(json).unwrap();
|
||||||
assert!(matches!(poll_answer.voter, Voter::Chat(_)));
|
assert!(poll_answer.voter.is_chat());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_poll_answer_with_both_user_and_voter_chat_de() {
|
fn poll_answer_with_both_user_and_voter_chat_de() {
|
||||||
let json = r#"{
|
let json = r#"{
|
||||||
"poll_id":"POLL_ID",
|
"poll_id":"POLL_ID",
|
||||||
"voter_chat": {
|
"voter_chat": {
|
||||||
|
@ -107,11 +84,11 @@ mod tests {
|
||||||
"title": "a",
|
"title": "a",
|
||||||
"type": "group"
|
"type": "group"
|
||||||
},
|
},
|
||||||
"user": {"id":136817688,"is_bot":true,"first_name":"Channel_Bot"},
|
"user": {"id": 136817688,"is_bot": true,"first_name": "Channel_Bot"},
|
||||||
"option_ids": []
|
"option_ids": []
|
||||||
}"#;
|
}"#;
|
||||||
|
|
||||||
let poll_answer: PollAnswer = serde_json::from_str(json).unwrap();
|
let poll_answer: PollAnswer = serde_json::from_str(json).unwrap();
|
||||||
assert!(matches!(poll_answer.voter, Voter::Chat(_)));
|
assert!(poll_answer.voter.is_chat());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -469,13 +469,14 @@ mod test {
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
Chat, ChatBoost, ChatBoostRemoved, ChatBoostSource, ChatBoostSourcePremium,
|
Chat, ChatBoost, ChatBoostRemoved, ChatBoostSource, ChatBoostSourcePremium,
|
||||||
ChatBoostUpdated, ChatFullInfo, ChatId, ChatKind, ChatPrivate, ChatPublic,
|
ChatBoostUpdated, ChatFullInfo, ChatId, ChatKind, ChatPrivate, ChatPublic,
|
||||||
LinkPreviewOptions, MediaKind, MediaText, Message, MessageCommon, MessageId, MessageKind,
|
LinkPreviewOptions, MaybeAnonymousUser, MediaKind, MediaText, Message, MessageCommon,
|
||||||
MessageReactionCountUpdated, MessageReactionUpdated, PublicChatChannel, PublicChatKind,
|
MessageId, MessageKind, MessageReactionCountUpdated, MessageReactionUpdated,
|
||||||
PublicChatSupergroup, ReactionCount, ReactionType, Update, UpdateId, UpdateKind, User,
|
PublicChatChannel, PublicChatKind, PublicChatSupergroup, ReactionCount, ReactionType,
|
||||||
UserId,
|
Update, UpdateId, UpdateKind, User, UserId,
|
||||||
};
|
};
|
||||||
|
|
||||||
use chrono::DateTime;
|
use chrono::DateTime;
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
// TODO: more tests for deserialization
|
// TODO: more tests for deserialization
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -892,7 +893,7 @@ mod test {
|
||||||
chat_full_info: ChatFullInfo::default(),
|
chat_full_info: ChatFullInfo::default(),
|
||||||
},
|
},
|
||||||
message_id: MessageId(35),
|
message_id: MessageId(35),
|
||||||
user: Some(User {
|
actor: MaybeAnonymousUser::User(User {
|
||||||
id: UserId(1459074222),
|
id: UserId(1459074222),
|
||||||
is_bot: false,
|
is_bot: false,
|
||||||
first_name: "shadowchain".to_owned(),
|
first_name: "shadowchain".to_owned(),
|
||||||
|
@ -902,7 +903,6 @@ mod test {
|
||||||
is_premium: true,
|
is_premium: true,
|
||||||
added_to_attachment_menu: false,
|
added_to_attachment_menu: false,
|
||||||
}),
|
}),
|
||||||
actor_chat: None,
|
|
||||||
date: DateTime::from_timestamp(1721306082, 0).unwrap(),
|
date: DateTime::from_timestamp(1721306082, 0).unwrap(),
|
||||||
old_reaction: vec![],
|
old_reaction: vec![],
|
||||||
new_reaction: vec![ReactionType::Emoji { emoji: "🌭".to_owned() }],
|
new_reaction: vec![ReactionType::Emoji { emoji: "🌭".to_owned() }],
|
||||||
|
@ -911,6 +911,78 @@ mod test {
|
||||||
|
|
||||||
let actual = serde_json::from_str::<Update>(json).unwrap();
|
let actual = serde_json::from_str::<Update>(json).unwrap();
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
|
|
||||||
|
let json = r#"
|
||||||
|
{
|
||||||
|
"update_id": 767844136,
|
||||||
|
"message_reaction": {
|
||||||
|
"chat": {
|
||||||
|
"id": -1002199793788,
|
||||||
|
"title": "тест",
|
||||||
|
"type": "supergroup"
|
||||||
|
},
|
||||||
|
"message_id": 2,
|
||||||
|
"actor_chat": {
|
||||||
|
"id": -1002199793788,
|
||||||
|
"title": "тест",
|
||||||
|
"type": "supergroup"
|
||||||
|
},
|
||||||
|
"date": 1723798597,
|
||||||
|
"old_reaction": [
|
||||||
|
{
|
||||||
|
"type": "emoji",
|
||||||
|
"emoji": "❤"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"new_reaction": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
let chat = Chat {
|
||||||
|
id: ChatId(-1002199793788),
|
||||||
|
kind: ChatKind::Public(ChatPublic {
|
||||||
|
title: Some("тест".to_owned()),
|
||||||
|
kind: PublicChatKind::Supergroup(PublicChatSupergroup {
|
||||||
|
username: None,
|
||||||
|
active_usernames: None,
|
||||||
|
is_forum: false,
|
||||||
|
sticker_set_name: None,
|
||||||
|
can_set_sticker_set: None,
|
||||||
|
permissions: None,
|
||||||
|
slow_mode_delay: None,
|
||||||
|
linked_chat_id: None,
|
||||||
|
location: None,
|
||||||
|
join_to_send_messages: None,
|
||||||
|
join_by_request: None,
|
||||||
|
custom_emoji_sticker_set_name: None,
|
||||||
|
unrestrict_boost_count: None,
|
||||||
|
}),
|
||||||
|
description: None,
|
||||||
|
invite_link: None,
|
||||||
|
has_protected_content: None,
|
||||||
|
}),
|
||||||
|
photo: None,
|
||||||
|
available_reactions: None,
|
||||||
|
pinned_message: None,
|
||||||
|
message_auto_delete_time: None,
|
||||||
|
has_hidden_members: false,
|
||||||
|
has_aggressive_anti_spam_enabled: false,
|
||||||
|
chat_full_info: ChatFullInfo::default(),
|
||||||
|
};
|
||||||
|
let expected = Update {
|
||||||
|
id: UpdateId(767844136),
|
||||||
|
kind: UpdateKind::MessageReaction(MessageReactionUpdated {
|
||||||
|
chat: chat.clone(),
|
||||||
|
message_id: MessageId(2),
|
||||||
|
actor: MaybeAnonymousUser::Chat(chat),
|
||||||
|
date: DateTime::from_timestamp(1723798597, 0).unwrap(),
|
||||||
|
old_reaction: vec![ReactionType::Emoji { emoji: "❤".to_owned() }],
|
||||||
|
new_reaction: vec![],
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
let actual = serde_json::from_str::<Update>(json).unwrap();
|
||||||
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in a new issue