From 690b029d9956cfcfe86692450d7b5ce9f0f15c19 Mon Sep 17 00:00:00 2001 From: Paul Woolcock Date: Sat, 8 Sep 2018 06:46:48 -0400 Subject: [PATCH] Add methods & data structures for all the "push" endpoints Closes #53 --- Cargo.toml | 2 + src/entities/mod.rs | 3 + src/entities/push.rs | 67 +++++ src/lib.rs | 59 +++- src/mastodon_client.rs | 20 +- src/requests/mod.rs | 3 + src/requests/push.rs | 633 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 770 insertions(+), 17 deletions(-) create mode 100644 src/entities/push.rs create mode 100644 src/requests/push.rs diff --git a/Cargo.toml b/Cargo.toml index 6b3d394..b336b20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,9 +19,11 @@ serde_derive = "1" serde_json = "1" serde_urlencoded = "0.5.3" url = "1" +tap-reader = "1" try_from = "0.2.2" toml = { version = "0.4.6", optional = true } + [dependencies.chrono] version = "0.4" features = ["serde"] diff --git a/src/entities/mod.rs b/src/entities/mod.rs index ec060ff..7c79bbb 100644 --- a/src/entities/mod.rs +++ b/src/entities/mod.rs @@ -15,6 +15,8 @@ pub mod list; pub mod mention; /// Data structures for ser/de of notification-related resources pub mod notification; +/// Data structures for ser/de of push-subscription-related resources +pub mod push; /// Data structures for ser/de of relationship-related resources pub mod relationship; /// Data structures for ser/de of report-related resources @@ -41,6 +43,7 @@ pub mod prelude { list::List, mention::Mention, notification::Notification, + push::Subscription, relationship::Relationship, report::Report, search_result::{SearchResult, SearchResultV2}, diff --git a/src/entities/push.rs b/src/entities/push.rs new file mode 100644 index 0000000..bcf826a --- /dev/null +++ b/src/entities/push.rs @@ -0,0 +1,67 @@ +/// Represents the `alerts` key of the `Subscription` object +#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Default)] +pub struct Alerts { + /// flag for follow alerts + pub follow: Option, + /// flag for favourite alerts + pub favourite: Option, + /// flag for reblog alerts + pub reblog: Option, + /// flag for mention alerts + pub mention: Option, +} + +/// Represents a new Push subscription +#[derive(Debug, Clone, PartialEq, Deserialize)] +pub struct Subscription { + /// The `id` of the subscription + pub id: String, + /// The endpoint of the subscription + pub endpoint: String, + /// The server key of the subscription + pub server_key: String, + /// The status of the alerts for this subscription + pub alerts: Option, +} + +pub(crate) mod add_subscription { + use super::Alerts; + + #[derive(Debug, Clone, PartialEq, Serialize, Default)] + pub(crate) struct Form { + pub(crate) subscription: Subscription, + pub(crate) data: Option, + } + + #[derive(Debug, Clone, PartialEq, Serialize, Default)] + pub(crate) struct Subscription { + pub(crate) endpoint: String, + pub(crate) keys: Keys, + } + + #[derive(Debug, Clone, PartialEq, Serialize, Default)] + pub(crate) struct Keys { + pub(crate) p256dh: String, + pub(crate) auth: String, + } + + #[derive(Debug, Clone, PartialEq, Serialize, Default)] + pub(crate) struct Data { + pub(crate) alerts: Option, + } +} + +pub(crate) mod update_data { + use super::Alerts; + + #[derive(Debug, Clone, PartialEq, Serialize, Default)] + pub(crate) struct Data { + pub(crate) alerts: Option, + } + + #[derive(Debug, Clone, PartialEq, Serialize, Default)] + pub(crate) struct Form { + pub(crate) id: String, + pub(crate) data: Data, + } +} diff --git a/src/lib.rs b/src/lib.rs index c159f38..c45e78f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,18 +9,21 @@ //! # try().unwrap(); //! # } //! # fn try() -> elefren::Result<()> { -//! use elefren::prelude::*; +//! use elefren::{helpers::cli, prelude::*}; //! //! let registration = Registration::new("https://mastodon.social") //! .client_name("elefren_test") //! .build()?; -//! let url = registration.authorize_url()?; -//! // Here you now need to open the url in the browser -//! // And handle a the redirect url coming back with the code. -//! let code = String::from("RETURNED_FROM_BROWSER"); -//! let mastodon = registration.complete(&code)?; +//! let mastodon = cli::authenticate(registration)?; //! -//! println!("{:?}", mastodon.get_home_timeline()?.initial_items); +//! println!( +//! "{:?}", +//! mastodon +//! .get_home_timeline()? +//! .items_iter() +//! .take(100) +//! .collect::>() +//! ); //! # Ok(()) //! # } //! ``` @@ -50,6 +53,7 @@ extern crate chrono; extern crate reqwest; extern crate serde; extern crate serde_urlencoded; +extern crate tap_reader; extern crate try_from; extern crate url; @@ -74,6 +78,7 @@ use reqwest::{ RequestBuilder, Response, }; +use tap_reader::Tap; use entities::prelude::*; use http_send::{HttpSend, HttpSender}; @@ -84,7 +89,7 @@ pub use errors::{ApiError, Error, Result}; pub use isolang::Language; pub use mastodon_client::MastodonClient; pub use registration::Registration; -pub use requests::{StatusesRequest, UpdateCredsRequest}; +pub use requests::{AddPushRequest, StatusesRequest, UpdateCredsRequest, UpdatePushRequest}; pub use status_builder::StatusBuilder; /// Registering your App @@ -191,6 +196,8 @@ impl MastodonClient for Mastodon { (post (uri: Cow<'static, str>,)) follows: "follows" => Account, (post multipart (file: Cow<'static, str>,)) media: "media" => Attachment, (post) clear_notifications: "notifications/clear" => Empty, + (get) get_push_subscription: "push/subscription" => Subscription, + (delete) delete_push_subscription: "push/subscription" => Empty, } route_v2! { @@ -345,6 +352,31 @@ impl MastodonClient for Mastodon { Page::new(self, response) } + + /// Add a push notifications subscription + fn add_push_subscription(&self, request: &AddPushRequest) -> Result { + let request = request.build()?; + let response = self.send( + self.client + .post(&self.route("/api/v1/push/subscription")) + .json(&request), + )?; + + deserialise(response) + } + + /// Update the `data` portion of the push subscription associated with this + /// access token + fn update_push_data(&self, request: &UpdatePushRequest) -> Result { + let request = request.build(); + let response = self.send( + self.client + .put(&self.route("/api/v1/push/subscription")) + .json(&request), + )?; + + deserialise(response) + } } impl ops::Deref for Mastodon { @@ -401,18 +433,15 @@ impl MastodonBuilder { // Convert the HTTP response body from JSON. Pass up deserialization errors // transparently. -fn deserialise serde::Deserialize<'de>>(mut response: Response) -> Result { - use std::io::Read; - - let mut vec = Vec::new(); - response.read_to_end(&mut vec)?; +fn deserialise serde::Deserialize<'de>>(response: Response) -> Result { + let mut reader = Tap::new(response); - match serde_json::from_slice(&vec) { + match serde_json::from_reader(&mut reader) { Ok(t) => Ok(t), // If deserializing into the desired type fails try again to // see if this is an error response. Err(e) => { - if let Ok(error) = serde_json::from_slice(&vec) { + if let Ok(error) = serde_json::from_slice(&reader.bytes) { return Err(Error::Api(error)); } Err(e.into()) diff --git a/src/mastodon_client.rs b/src/mastodon_client.rs index a7e96a8..827abee 100644 --- a/src/mastodon_client.rs +++ b/src/mastodon_client.rs @@ -4,7 +4,7 @@ use entities::prelude::*; use errors::Result; use http_send::{HttpSend, HttpSender}; use page::Page; -use requests::{StatusesRequest, UpdateCredsRequest}; +use requests::{AddPushRequest, StatusesRequest, UpdateCredsRequest, UpdatePushRequest}; use status_builder::StatusBuilder; /// Represents the set of methods that a Mastodon Client can do, so that @@ -198,7 +198,7 @@ pub trait MastodonClient { { unimplemented!("This method was not implemented"); } - /// GET /api/v1/accounts/relationships? + /// GET /api/v1/accounts/relationships fn relationships(&self, ids: &[&str]) -> Result> { unimplemented!("This method was not implemented"); } @@ -211,4 +211,20 @@ pub trait MastodonClient { ) -> Result> { unimplemented!("This method was not implemented"); } + /// POST /api/v1/push/subscription + fn add_push_subscription(&self, request: &AddPushRequest) -> Result { + unimplemented!("This method was not implemented"); + } + /// PUT /api/v1/push/subscription + fn update_push_data(&self, request: &UpdatePushRequest) -> Result { + unimplemented!("This method was not implemented"); + } + /// GET /api/v1/push/subscription + fn get_push_subscription(&self) -> Result { + unimplemented!("This method was not implemented"); + } + /// DELETE /api/v1/push/subscription + fn delete_push_subscription(&self) -> Result { + unimplemented!("This method was not implemented"); + } } diff --git a/src/requests/mod.rs b/src/requests/mod.rs index bb3f1ae..31785aa 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -1,7 +1,10 @@ +/// Data structure for the MastodonClient::add_push_subscription method +pub use self::push::{AddPushRequest, Keys, UpdatePushRequest}; /// Data structure for the MastodonClient::statuses method pub use self::statuses::StatusesRequest; /// Data structure for the MastodonClient::update_credentials method pub use self::update_credentials::UpdateCredsRequest; +mod push; mod statuses; mod update_credentials; diff --git a/src/requests/push.rs b/src/requests/push.rs new file mode 100644 index 0000000..c609b07 --- /dev/null +++ b/src/requests/push.rs @@ -0,0 +1,633 @@ +use entities::push::{add_subscription, update_data}; +use errors::Result; + +/// Container for the key & auth strings for an AddPushRequest +/// +/// # Example +/// +/// ``` +/// # extern crate elefren; +/// use elefren::requests::Keys; +/// +/// let keys = Keys::new("anetohias===", "oeatssah="); +/// ``` +#[derive(Debug, Default, Clone, PartialEq)] +pub struct Keys { + pub(crate) p256dh: String, + pub(crate) auth: String, +} + +impl Keys { + /// Create the `Keys` container + /// + /// # Example + /// + /// ``` + /// # extern crate elefren; + /// use elefren::requests::Keys; + /// + /// let keys = Keys::new("anetohias===", "oeatssah="); + /// ``` + pub fn new(p256dh: &str, auth: &str) -> Keys { + Keys { + p256dh: p256dh.to_string(), + auth: auth.to_string(), + } + } +} + +/// Builder to pass to the Mastodon::add_push_subscription method +/// +/// # Example +/// +/// ```no_run +/// # extern crate elefren; +/// # use elefren::{MastodonClient, Mastodon, Data}; +/// # fn main() -> Result<(), elefren::Error> { +/// # let data = Data { +/// # base: "".into(), +/// # client_id: "".into(), +/// # client_secret: "".into(), +/// # redirect: "".into(), +/// # token: "".into(), +/// # }; +/// use elefren::requests::{AddPushRequest, Keys}; +/// +/// let client = Mastodon::from(data); +/// +/// let keys = Keys::new("stahesuahoei293ise===", "tasecoa,nmeozka=="); +/// let mut request = AddPushRequest::new("http://example.com/push/endpoint", &keys); +/// request.follow().reblog(); +/// +/// client.add_push_subscription(&request)?; +/// # Ok(()) +/// # } +/// ``` +#[derive(Debug, Default, Clone, PartialEq)] +pub struct AddPushRequest { + endpoint: String, + + p256dh: String, + auth: String, + + follow: Option, + favourite: Option, + reblog: Option, + mention: Option, +} + +impl AddPushRequest { + /// Construct a new AddPushRequest + /// + /// # Example + /// + /// ``` + /// # extern crate elefren; + /// use elefren::requests::{AddPushRequest, Keys}; + /// let keys = Keys::new("abcdef===", "foobar=="); + /// let push_endpoint = "https://example.com/push/endpoint"; + /// let request = AddPushRequest::new(push_endpoint, &keys); + /// ``` + pub fn new(endpoint: &str, keys: &Keys) -> AddPushRequest { + AddPushRequest { + endpoint: endpoint.to_string(), + p256dh: keys.p256dh.clone(), + auth: keys.auth.clone(), + ..Default::default() + } + } + + /// A flag that indicates if you want follow notifications pushed + /// + /// # Example + /// ``` + /// # extern crate elefren; + /// use elefren::requests::{AddPushRequest, Keys}; + /// let keys = Keys::new("abcdef===", "foobar=="); + /// let push_endpoint = "https://example.com/push/endpoint"; + /// let mut request = AddPushRequest::new(push_endpoint, &keys); + /// request.follow(); + /// ``` + pub fn follow(&mut self) -> &mut Self { + self.follow = Some(true); + self + } + + /// A flag that indicates if you want favourite notifications pushed + /// + /// # Example + /// ``` + /// # extern crate elefren; + /// use elefren::requests::{AddPushRequest, Keys}; + /// let keys = Keys::new("abcdef===", "foobar=="); + /// let push_endpoint = "https://example.com/push/endpoint"; + /// let mut request = AddPushRequest::new(push_endpoint, &keys); + /// request.favourite(); + /// ``` + pub fn favourite(&mut self) -> &mut Self { + self.favourite = Some(true); + self + } + + /// A flag that indicates if you want reblog notifications pushed + /// + /// # Example + /// ``` + /// # extern crate elefren; + /// use elefren::requests::{AddPushRequest, Keys}; + /// let keys = Keys::new("abcdef===", "foobar=="); + /// let push_endpoint = "https://example.com/push/endpoint"; + /// let mut request = AddPushRequest::new(push_endpoint, &keys); + /// request.reblog(); + /// ``` + pub fn reblog(&mut self) -> &mut Self { + self.reblog = Some(true); + self + } + + /// A flag that indicates if you want mention notifications pushed + /// + /// # Example + /// ``` + /// # extern crate elefren; + /// use elefren::requests::{AddPushRequest, Keys}; + /// let keys = Keys::new("abcdef===", "foobar=="); + /// let push_endpoint = "https://example.com/push/endpoint"; + /// let mut request = AddPushRequest::new(push_endpoint, &keys); + /// request.mention(); + /// ``` + pub fn mention(&mut self) -> &mut Self { + self.mention = Some(true); + self + } + + fn flags_present(&self) -> bool { + self.follow.is_some() + || self.favourite.is_some() + || self.reblog.is_some() + || self.mention.is_some() + } + + pub(crate) fn build(&self) -> Result { + use entities::push::{ + add_subscription::{Data, Form, Keys, Subscription}, + Alerts, + }; + let mut form = Form { + subscription: Subscription { + endpoint: self.endpoint.clone(), + keys: Keys { + p256dh: self.p256dh.clone(), + auth: self.auth.clone(), + }, + }, + data: None, + }; + if self.flags_present() { + let mut alerts = Alerts::default(); + + if let Some(follow) = self.follow { + alerts.follow = Some(follow); + } + + if let Some(favourite) = self.favourite { + alerts.favourite = Some(favourite); + } + + if let Some(reblog) = self.reblog { + alerts.reblog = Some(reblog); + } + + if let Some(mention) = self.mention { + alerts.mention = Some(mention); + } + + form.data = Some(Data { + alerts: Some(alerts), + }); + } + Ok(form) + } +} + +/// Builder to pass to the Mastodon::update_push_data method +/// +/// # Example +/// +/// ```no_run +/// # extern crate elefren; +/// # use elefren::{MastodonClient, Mastodon, Data}; +/// # fn main() -> Result<(), elefren::Error> { +/// # let data = Data { +/// # base: "".into(), +/// # client_id: "".into(), +/// # client_secret: "".into(), +/// # redirect: "".into(), +/// # token: "".into(), +/// # }; +/// use elefren::requests::UpdatePushRequest; +/// +/// let client = Mastodon::from(data); +/// +/// let mut request = UpdatePushRequest::new("foobar"); +/// request.follow(true).reblog(true); +/// +/// client.update_push_data(&request)?; +/// # Ok(()) +/// # } +/// ``` +#[derive(Debug, Default, Clone, PartialEq, Serialize)] +pub struct UpdatePushRequest { + id: String, + follow: Option, + favourite: Option, + reblog: Option, + mention: Option, +} + +impl UpdatePushRequest { + /// Construct a new UpdatePushRequest + /// + /// # Example + /// + /// ``` + /// # extern crate elefren; + /// use elefren::requests::UpdatePushRequest; + /// let request = UpdatePushRequest::new("some-id"); + /// ``` + pub fn new(id: &str) -> UpdatePushRequest { + UpdatePushRequest { + id: id.to_string(), + ..Default::default() + } + } + + /// A flag that indicates if you want follow notifications pushed + /// + /// # Example + /// ``` + /// # extern crate elefren; + /// use elefren::requests::UpdatePushRequest; + /// let mut request = UpdatePushRequest::new("foobar"); + /// request.follow(true); + /// ``` + pub fn follow(&mut self, follow: bool) -> &mut Self { + self.follow = Some(follow); + self + } + + /// A flag that indicates if you want favourite notifications pushed + /// + /// # Example + /// ``` + /// # extern crate elefren; + /// use elefren::requests::UpdatePushRequest; + /// let mut request = UpdatePushRequest::new("foobar"); + /// request.favourite(true); + /// ``` + pub fn favourite(&mut self, favourite: bool) -> &mut Self { + self.favourite = Some(favourite); + self + } + + /// A flag that indicates if you want reblog notifications pushed + /// + /// # Example + /// ``` + /// # extern crate elefren; + /// use elefren::requests::UpdatePushRequest; + /// let mut request = UpdatePushRequest::new("foobar"); + /// request.reblog(true); + /// ``` + pub fn reblog(&mut self, reblog: bool) -> &mut Self { + self.reblog = Some(reblog); + self + } + + /// A flag that indicates if you want mention notifications pushed + /// + /// # Example + /// ``` + /// # extern crate elefren; + /// use elefren::requests::UpdatePushRequest; + /// let mut request = UpdatePushRequest::new("foobar"); + /// request.mention(true); + /// ``` + pub fn mention(&mut self, mention: bool) -> &mut Self { + self.mention = Some(mention); + self + } + + fn flags_present(&self) -> bool { + self.follow.is_some() + || self.favourite.is_some() + || self.reblog.is_some() + || self.mention.is_some() + } + + pub(crate) fn build(&self) -> update_data::Form { + use entities::push::{ + update_data::{Data, Form}, + Alerts, + }; + + let mut form = Form { + id: self.id.clone(), + ..Default::default() + }; + + if self.flags_present() { + let mut alerts = Alerts::default(); + if let Some(follow) = self.follow { + alerts.follow = Some(follow); + } + if let Some(favourite) = self.favourite { + alerts.favourite = Some(favourite); + } + if let Some(reblog) = self.reblog { + alerts.reblog = Some(reblog); + } + if let Some(mention) = self.mention { + alerts.mention = Some(mention); + } + form.data = Data { + alerts: Some(alerts), + }; + } + form + } +} + +#[cfg(test)] +mod tests { + use super::*; + use entities::push::{add_subscription, update_data, Alerts}; + + #[test] + fn test_keys_new() { + let keys = Keys::new("anetohias===", "oeatssah="); + assert_eq!( + keys, + Keys { + p256dh: "anetohias===".to_string(), + auth: "oeatssah=".to_string() + } + ); + } + + #[test] + fn test_add_push_request_new() { + let endpoint = "https://example.com/push/endpoint"; + let keys = Keys::new("anetohias===", "oeatssah="); + let req = AddPushRequest::new(endpoint, &keys); + assert_eq!( + req, + AddPushRequest { + endpoint: "https://example.com/push/endpoint".to_string(), + p256dh: "anetohias===".to_string(), + auth: "oeatssah=".to_string(), + follow: None, + favourite: None, + reblog: None, + mention: None, + } + ); + } + #[test] + fn test_add_push_request_follow() { + let endpoint = "https://example.com/push/endpoint"; + let keys = Keys::new("anetohias===", "oeatssah="); + let mut req = AddPushRequest::new(endpoint, &keys); + req.follow(); + assert_eq!( + req, + AddPushRequest { + endpoint: "https://example.com/push/endpoint".to_string(), + p256dh: "anetohias===".to_string(), + auth: "oeatssah=".to_string(), + follow: Some(true), + favourite: None, + reblog: None, + mention: None, + } + ); + } + + #[test] + fn test_add_push_request_favourite() { + let endpoint = "https://example.com/push/endpoint"; + let keys = Keys::new("anetohias===", "oeatssah="); + let mut req = AddPushRequest::new(endpoint, &keys); + req.favourite(); + assert_eq!( + req, + AddPushRequest { + endpoint: "https://example.com/push/endpoint".to_string(), + p256dh: "anetohias===".to_string(), + auth: "oeatssah=".to_string(), + follow: None, + favourite: Some(true), + reblog: None, + mention: None, + } + ); + } + #[test] + fn test_add_push_request_reblog() { + let endpoint = "https://example.com/push/endpoint"; + let keys = Keys::new("anetohias===", "oeatssah="); + let mut req = AddPushRequest::new(endpoint, &keys); + req.reblog(); + assert_eq!( + req, + AddPushRequest { + endpoint: "https://example.com/push/endpoint".to_string(), + p256dh: "anetohias===".to_string(), + auth: "oeatssah=".to_string(), + follow: None, + favourite: None, + reblog: Some(true), + mention: None, + } + ); + } + #[test] + fn test_add_push_request_mention() { + let endpoint = "https://example.com/push/endpoint"; + let keys = Keys::new("anetohias===", "oeatssah="); + let mut req = AddPushRequest::new(endpoint, &keys); + req.mention(); + assert_eq!( + req, + AddPushRequest { + endpoint: "https://example.com/push/endpoint".to_string(), + p256dh: "anetohias===".to_string(), + auth: "oeatssah=".to_string(), + follow: None, + favourite: None, + reblog: None, + mention: Some(true), + } + ); + } + #[test] + fn test_add_push_request_build_no_flags() { + let endpoint = "https://example.com/push/endpoint"; + let keys = Keys::new("anetohias===", "oeatssah="); + let req = AddPushRequest::new(endpoint, &keys); + let form = req.build().expect("Couldn't build form"); + assert_eq!( + form, + add_subscription::Form { + subscription: add_subscription::Subscription { + endpoint: "https://example.com/push/endpoint".to_string(), + keys: add_subscription::Keys { + p256dh: "anetohias===".to_string(), + auth: "oeatssah=".to_string(), + }, + }, + data: None, + } + ); + } + + #[test] + fn test_add_push_request_build() { + let endpoint = "https://example.com/push/endpoint"; + let keys = Keys::new("anetohias===", "oeatssah="); + let mut req = AddPushRequest::new(endpoint, &keys); + req.follow().reblog(); + let form = req.build().expect("Couldn't build form"); + assert_eq!( + form, + add_subscription::Form { + subscription: add_subscription::Subscription { + endpoint: "https://example.com/push/endpoint".to_string(), + keys: add_subscription::Keys { + p256dh: "anetohias===".to_string(), + auth: "oeatssah=".to_string(), + }, + }, + data: Some(add_subscription::Data { + alerts: Some(Alerts { + follow: Some(true), + favourite: None, + reblog: Some(true), + mention: None, + }), + }), + } + ); + } + + #[test] + fn test_update_push_request_new() { + let req = UpdatePushRequest::new("some-id"); + assert_eq!( + req, + UpdatePushRequest { + id: "some-id".to_string(), + follow: None, + favourite: None, + reblog: None, + mention: None, + } + ); + } + + #[test] + fn test_update_push_request_follow() { + let mut req = UpdatePushRequest::new("some-id"); + req.follow(true); + assert_eq!( + req, + UpdatePushRequest { + id: "some-id".to_string(), + follow: Some(true), + favourite: None, + reblog: None, + mention: None, + } + ); + } + #[test] + fn test_update_push_request_favourite() { + let mut req = UpdatePushRequest::new("some-id"); + req.favourite(true); + assert_eq!( + req, + UpdatePushRequest { + id: "some-id".to_string(), + follow: None, + favourite: Some(true), + reblog: None, + mention: None, + } + ); + } + #[test] + fn test_update_push_request_reblog() { + let mut req = UpdatePushRequest::new("some-id"); + req.reblog(true); + assert_eq!( + req, + UpdatePushRequest { + id: "some-id".to_string(), + follow: None, + favourite: None, + reblog: Some(true), + mention: None, + } + ); + } + #[test] + fn test_update_push_request_mention() { + let mut req = UpdatePushRequest::new("some-id"); + req.mention(true); + assert_eq!( + req, + UpdatePushRequest { + id: "some-id".to_string(), + follow: None, + favourite: None, + reblog: None, + mention: Some(true), + } + ); + } + #[test] + fn test_update_push_request_build_no_flags() { + let req = UpdatePushRequest::new("some-id"); + let form = req.build(); + assert_eq!( + form, + update_data::Form { + id: "some-id".to_string(), + data: update_data::Data { + alerts: None, + }, + } + ); + } + + #[test] + fn test_update_push_request_build() { + let mut req = UpdatePushRequest::new("some-id"); + req.favourite(false); + let form = req.build(); + assert_eq!( + form, + update_data::Form { + id: "some-id".to_string(), + data: update_data::Data { + alerts: Some(Alerts { + follow: None, + favourite: Some(false), + reblog: None, + mention: None, + }), + }, + } + ); + } +}