Convert PaymentOption type into enum
This commit is contained in:
parent
318d446dbd
commit
742e731b95
5 changed files with 93 additions and 77 deletions
|
@ -15,8 +15,8 @@ use crate::frontend::get_subscription_page_url;
|
|||
use crate::models::profiles::types::{
|
||||
ExtraField,
|
||||
IdentityProof,
|
||||
PaymentLink,
|
||||
PaymentOption,
|
||||
PaymentType,
|
||||
};
|
||||
use super::types::ActorAttachment;
|
||||
|
||||
|
@ -67,10 +67,10 @@ pub fn attach_payment_option(
|
|||
user_id: &Uuid,
|
||||
payment_option: PaymentOption,
|
||||
) -> ActorAttachment {
|
||||
match payment_option.payment_type {
|
||||
PaymentType::Link => unimplemented!(),
|
||||
PaymentType::EthereumSubscription => {
|
||||
let name = format!("{:?}", payment_option.payment_type);
|
||||
match payment_option {
|
||||
PaymentOption::Link(_) => unimplemented!(),
|
||||
PaymentOption::EthereumSubscription => {
|
||||
let name = "EthereumSubscription".to_string();
|
||||
let subscription_page_url =
|
||||
get_subscription_page_url(instance_url, user_id);
|
||||
ActorAttachment {
|
||||
|
@ -91,11 +91,13 @@ pub fn parse_payment_option(
|
|||
if attachment.object_type != LINK {
|
||||
return Err(ValidationError("invalid attachment type"));
|
||||
};
|
||||
let payment_option = PaymentOption {
|
||||
payment_type: PaymentType::Link,
|
||||
name: Some(attachment.name.clone()),
|
||||
href: attachment.href.clone(),
|
||||
};
|
||||
let href = attachment.href.as_ref()
|
||||
.ok_or(ValidationError("href attribute is required"))?
|
||||
.to_string();
|
||||
let payment_option = PaymentOption::Link(PaymentLink {
|
||||
name: attachment.name.clone(),
|
||||
href: href,
|
||||
});
|
||||
Ok(payment_option)
|
||||
}
|
||||
|
||||
|
@ -153,7 +155,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_payment_option() {
|
||||
let user_id = new_uuid();
|
||||
let payment_option = PaymentOption::subscription();
|
||||
let payment_option = PaymentOption::EthereumSubscription;
|
||||
let subscription_page_url =
|
||||
format!("https://example.com/profile/{}/subscription", user_id);
|
||||
let attachment = attach_payment_option(
|
||||
|
@ -166,8 +168,11 @@ mod tests {
|
|||
assert_eq!(attachment.href.as_deref().unwrap(), subscription_page_url);
|
||||
|
||||
let parsed_option = parse_payment_option(&attachment).unwrap();
|
||||
assert!(matches!(parsed_option.payment_type, PaymentType::Link));
|
||||
assert_eq!(parsed_option.name.unwrap(), "EthereumSubscription");
|
||||
assert_eq!(parsed_option.href.unwrap(), subscription_page_url);
|
||||
let link = match parsed_option {
|
||||
PaymentOption::Link(link) => link,
|
||||
_ => panic!("wrong option"),
|
||||
};
|
||||
assert_eq!(link.name, "EthereumSubscription");
|
||||
assert_eq!(link.href, subscription_page_url);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ use crate::models::profiles::types::{
|
|||
ExtraField,
|
||||
IdentityProof,
|
||||
PaymentOption,
|
||||
PaymentType,
|
||||
ProfileUpdateData,
|
||||
};
|
||||
use crate::models::profiles::validators::validate_username;
|
||||
|
@ -97,9 +96,9 @@ impl Account {
|
|||
let subscription_page_url = profile.payment_options.clone()
|
||||
.into_inner().into_iter()
|
||||
.map(|option| {
|
||||
match option.payment_type {
|
||||
PaymentType::Link => option.href.unwrap_or_default(),
|
||||
PaymentType::EthereumSubscription => {
|
||||
match option {
|
||||
PaymentOption::Link(link) => link.href,
|
||||
PaymentOption::EthereumSubscription => {
|
||||
get_subscription_page_url(instance_url, &profile.id)
|
||||
},
|
||||
}
|
||||
|
|
|
@ -345,7 +345,7 @@ async fn subscriptions_enabled(
|
|||
if current_user.profile.payment_options.is_empty() {
|
||||
// Add payment option to profile
|
||||
let mut profile_data = ProfileUpdateData::from(¤t_user.profile);
|
||||
profile_data.payment_options = vec![PaymentOption::subscription()];
|
||||
profile_data.payment_options = vec![PaymentOption::EthereumSubscription];
|
||||
current_user.profile = update_profile(
|
||||
db_client,
|
||||
¤t_user.id,
|
||||
|
|
|
@ -5,6 +5,8 @@ use postgres_types::FromSql;
|
|||
use serde::{
|
||||
Deserialize, Deserializer, Serialize, Serializer,
|
||||
de::Error as DeserializerError,
|
||||
ser::SerializeMap,
|
||||
__private::ser::FlatMapSerializer,
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -16,7 +18,6 @@ use crate::ethereum::identity::DidPkh;
|
|||
use super::validators::{
|
||||
validate_username,
|
||||
validate_display_name,
|
||||
validate_payment_options,
|
||||
clean_bio,
|
||||
clean_extra_fields,
|
||||
};
|
||||
|
@ -41,7 +42,6 @@ impl IdentityProofs {
|
|||
json_from_sql!(IdentityProofs);
|
||||
json_to_sql!(IdentityProofs);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum PaymentType {
|
||||
Link,
|
||||
EthereumSubscription,
|
||||
|
@ -69,38 +69,58 @@ impl TryFrom<i16> for PaymentType {
|
|||
}
|
||||
}
|
||||
|
||||
impl Serialize for PaymentType {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where S: Serializer
|
||||
{
|
||||
let value: i16 = self.into();
|
||||
serializer.serialize_i16(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for PaymentType {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where D: Deserializer<'de>
|
||||
{
|
||||
let value: i16 = Deserialize::deserialize(deserializer)?;
|
||||
Self::try_from(value).map_err(DeserializerError::custom)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct PaymentOption {
|
||||
pub payment_type: PaymentType,
|
||||
pub name: Option<String>,
|
||||
pub href: Option<String>,
|
||||
pub struct PaymentLink {
|
||||
pub name: String,
|
||||
pub href: String,
|
||||
}
|
||||
|
||||
impl PaymentOption {
|
||||
pub fn subscription() -> Self {
|
||||
Self {
|
||||
payment_type: PaymentType::EthereumSubscription,
|
||||
name: None,
|
||||
href: None,
|
||||
}
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum PaymentOption {
|
||||
Link(PaymentLink),
|
||||
EthereumSubscription,
|
||||
}
|
||||
|
||||
// Integer tags are not supported https://github.com/serde-rs/serde/issues/745
|
||||
// Workaround: https://stackoverflow.com/a/65576570
|
||||
impl<'de> Deserialize<'de> for PaymentOption {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where D: Deserializer<'de>
|
||||
{
|
||||
let value = serde_json::Value::deserialize(deserializer)?;
|
||||
let payment_type = value.get("payment_type")
|
||||
.and_then(serde_json::Value::as_u64)
|
||||
.and_then(|val| i16::try_from(val).ok())
|
||||
.and_then(|val| PaymentType::try_from(val).ok())
|
||||
.ok_or(DeserializerError::custom("invalid payment type"))?;
|
||||
let payment_option = match payment_type {
|
||||
PaymentType::Link => {
|
||||
let link = PaymentLink::deserialize(value)
|
||||
.map_err(DeserializerError::custom)?;
|
||||
Self::Link(link)
|
||||
},
|
||||
PaymentType::EthereumSubscription => Self::EthereumSubscription,
|
||||
};
|
||||
Ok(payment_option)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for PaymentOption {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where S: Serializer,
|
||||
{
|
||||
let mut map = serializer.serialize_map(None)?;
|
||||
let payment_type = match self {
|
||||
Self::Link(_) => PaymentType::Link,
|
||||
Self::EthereumSubscription => PaymentType::EthereumSubscription,
|
||||
};
|
||||
map.serialize_entry("payment_type", &i16::from(&payment_type))?;
|
||||
|
||||
match self {
|
||||
Self::Link(link) => link.serialize(FlatMapSerializer(&mut map))?,
|
||||
Self::EthereumSubscription => (),
|
||||
};
|
||||
map.end()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,7 +288,6 @@ impl ProfileCreateData {
|
|||
let cleaned_bio = clean_bio(bio, self.actor_json.is_some())?;
|
||||
self.bio = Some(cleaned_bio);
|
||||
};
|
||||
validate_payment_options(&self.payment_options)?;
|
||||
self.extra_fields = clean_extra_fields(&self.extra_fields)?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -296,7 +315,6 @@ impl ProfileUpdateData {
|
|||
let cleaned_bio = clean_bio(bio, self.actor_json.is_some())?;
|
||||
self.bio = Some(cleaned_bio);
|
||||
};
|
||||
validate_payment_options(&self.payment_options)?;
|
||||
self.extra_fields = clean_extra_fields(&self.extra_fields)?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -336,15 +354,29 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_payment_option_serialization() {
|
||||
fn test_payment_option_link_serialization() {
|
||||
let json_data = r#"{"payment_type":1,"name":"test","href":"https://test.com"}"#;
|
||||
let payment_option: PaymentOption = serde_json::from_str(json_data).unwrap();
|
||||
let link = match payment_option {
|
||||
PaymentOption::Link(ref link) => link,
|
||||
_ => panic!("wrong option"),
|
||||
};
|
||||
assert_eq!(link.name, "test");
|
||||
assert_eq!(link.href, "https://test.com");
|
||||
let serialized = serde_json::to_string(&payment_option).unwrap();
|
||||
assert_eq!(serialized, json_data);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_payment_option_ethereum_subscription_serialization() {
|
||||
let json_data = r#"{"payment_type":2,"name":null,"href":null}"#;
|
||||
let payment_option: PaymentOption = serde_json::from_str(json_data).unwrap();
|
||||
assert!(matches!(
|
||||
payment_option.payment_type,
|
||||
PaymentType::EthereumSubscription,
|
||||
payment_option,
|
||||
PaymentOption::EthereumSubscription,
|
||||
));
|
||||
let serialized = serde_json::to_string(&payment_option).unwrap();
|
||||
assert_eq!(serialized, json_data);
|
||||
assert_eq!(serialized, r#"{"payment_type":2}"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use regex::Regex;
|
||||
use crate::errors::ValidationError;
|
||||
use crate::utils::html::{clean_html, clean_html_strict};
|
||||
use super::types::{ExtraField, PaymentOption, PaymentType};
|
||||
use super::types::ExtraField;
|
||||
|
||||
const USERNAME_RE: &str = r"^[a-zA-Z0-9_\.-]+$";
|
||||
|
||||
|
@ -46,26 +46,6 @@ pub fn clean_bio(bio: &str, is_remote: bool) -> Result<String, ValidationError>
|
|||
Ok(cleaned_bio)
|
||||
}
|
||||
|
||||
pub fn validate_payment_options(payment_options: &[PaymentOption])
|
||||
-> Result<(), ValidationError>
|
||||
{
|
||||
for option in payment_options {
|
||||
match option.payment_type {
|
||||
PaymentType::Link => {
|
||||
if option.name.is_none() || option.href.is_none() {
|
||||
return Err(ValidationError("invalid payment option"));
|
||||
};
|
||||
},
|
||||
PaymentType::EthereumSubscription => {
|
||||
if option.name.is_some() || option.href.is_some() {
|
||||
return Err(ValidationError("invalid payment option"));
|
||||
};
|
||||
},
|
||||
};
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
const FIELD_NAME_MAX_SIZE: usize = 500;
|
||||
const FIELD_VALUE_MAX_SIZE: usize = 5000;
|
||||
|
||||
|
|
Loading…
Reference in a new issue