Skip to content

Commit e89c618

Browse files
committed
Merge pull request #289 from mzeitlin11/id_testing
Add some ser de testing for ids
2 parents ec37e88 + d439571 commit e89c618

File tree

1 file changed

+85
-1
lines changed

1 file changed

+85
-1
lines changed

src/ids.rs

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ def_id!(PlanId: String); // N.B. A plan id can be user-provided so can be any ar
551551
def_id!(PlatformTaxFeeId, "ptf");
552552
def_id!(PriceId, "price_");
553553
def_id!(ProductId: String); // N.B. A product id can be user-provided so can be any arbitrary string
554-
def_id!(PromotionCodeId, "promo_"); // N.B. A product id can be user-provided so can be any arbitrary string
554+
def_id!(PromotionCodeId, "promo_");
555555
def_id!(QuoteId, "qt_");
556556
def_id!(RecipientId: String); // FIXME: This doesn't seem to be documented yet
557557
def_id!(RefundId, "re_" | "pyr_");
@@ -634,8 +634,92 @@ impl<'de> serde::Deserialize<'de> for InvoiceId {
634634

635635
#[cfg(test)]
636636
mod tests {
637+
use std::fmt::{Debug, Display};
638+
use std::str::FromStr;
639+
640+
use serde::de::DeserializeOwned;
641+
use serde::{Deserialize, Serialize};
642+
use serde_json::json;
643+
637644
use super::*;
638645

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

0 commit comments

Comments
 (0)