Skip to content

Commit b55f10c

Browse files
committed
Add some ser de testing for ids
1 parent 4faee55 commit b55f10c

File tree

1 file changed

+86
-1
lines changed

1 file changed

+86
-1
lines changed

src/ids.rs

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ def_id!(PlanId: String); // N.B. A plan id can be user-provided so can be any ar
539539
def_id!(PlatformTaxFeeId, "ptf");
540540
def_id!(PriceId, "price_");
541541
def_id!(ProductId: String); // N.B. A product id can be user-provided so can be any arbitrary string
542-
def_id!(PromotionCodeId, "promo_"); // N.B. A product id can be user-provided so can be any arbitrary string
542+
def_id!(PromotionCodeId, "promo_");
543543
def_id!(QuoteId, "qt_");
544544
def_id!(RecipientId: String); // FIXME: This doesn't seem to be documented yet
545545
def_id!(RefundId, "re_" | "pyr_");
@@ -622,8 +622,93 @@ impl<'de> serde::Deserialize<'de> for InvoiceId {
622622

623623
#[cfg(test)]
624624
mod tests {
625+
use std::fmt::{Debug, Display};
626+
use std::str::FromStr;
627+
628+
use http_types::convert::Deserialize;
629+
use serde::de::DeserializeOwned;
630+
use serde::Serialize;
631+
use serde_json::json;
632+
625633
use super::*;
626634

635+
fn assert_ser_de_roundtrip<T>(id: &str)
636+
where
637+
T: DeserializeOwned + Serialize + FromStr + Display + Debug,
638+
<T as FromStr>::Err: Debug,
639+
{
640+
let parsed_id = T::from_str(id).expect("Could not parse id");
641+
let ser = serde_json::to_string(&parsed_id).expect("Could not serialize id");
642+
let deser: T = serde_json::from_str(&ser).expect("Could not deserialize id");
643+
assert_eq!(deser.to_string(), id.to_string());
644+
}
645+
646+
fn assert_deser_err<T: DeserializeOwned + Debug>(id: &str) {
647+
let json_str = format!(r#""{}""#, id);
648+
let deser: Result<T, _> = serde_json::from_str(&json_str);
649+
assert!(deser.is_err(), "Expected error, got {:?}", deser);
650+
}
651+
652+
#[test]
653+
fn test_empty_invoice_id_default() {
654+
#[derive(Deserialize)]
655+
struct WithInvoiceId {
656+
id: InvoiceId,
657+
}
658+
659+
for body in [json!({"id": ""}), json!({})] {
660+
let deser: WithInvoiceId = serde_json::from_value(body).expect("Could not deser");
661+
assert_eq!(deser.id, InvoiceId::none());
662+
}
663+
}
664+
665+
#[test]
666+
fn test_ser_de_roundtrip() {
667+
// InvoiceId special cased
668+
for id in ["in_12345", "in_"] {
669+
assert_ser_de_roundtrip::<InvoiceId>(id);
670+
}
671+
672+
// Single prefix
673+
assert_ser_de_roundtrip::<PriceId>("price_abc");
674+
675+
// Case where multiple possible prefixes
676+
for id in ["re_bcd", "pyr_123"] {
677+
assert_ser_de_roundtrip::<RefundId>(id);
678+
}
679+
680+
// Case where id can be anything
681+
for id in ["anything", ""] {
682+
assert_ser_de_roundtrip::<ProductId>(id);
683+
}
684+
685+
// Case where enum id
686+
for id in ["tok_123", "btok_456"] {
687+
assert_ser_de_roundtrip::<TokenId>(id);
688+
}
689+
}
690+
691+
#[test]
692+
fn test_deser_err() {
693+
// InvoiceId special cased
694+
assert_deser_err::<InvoiceId>("in");
695+
696+
// Single prefix
697+
for id in ["sub", ""] {
698+
assert_deser_err::<SubscriptionId>(id);
699+
}
700+
701+
// Case where multiple possible prefixes
702+
for id in ["abc_bcd", "pyr_123"] {
703+
assert_deser_err::<PaymentMethodId>(id);
704+
}
705+
706+
// Case where enum id
707+
for id in ["tok_123", "btok_456"] {
708+
assert_deser_err::<PaymentSourceId>(id);
709+
}
710+
}
711+
627712
#[test]
628713
fn test_parse_customer() {
629714
assert!("cus_123".parse::<CustomerId>().is_ok());

0 commit comments

Comments
 (0)