//! Stripe id parsing at the boundary between our database and Stripe's API. //! These ids come out of our own rows, so a parse failure means our data is //! wrong, and the classification matters: `Internal` pages us, `BadRequest` //! would blame the creator for our own corrupted column. use super::*; #[test] fn account_id_parsing_rejects_nothing_at_all() { // Same dead guard as `parse_subscription_id`. `stripe_shared::AccountId` // derives `FromStr` with `type Err = Infallible`, so every value parses // and the `Invalid Stripe account ID` branch cannot be reached. The doc // comment above reasons carefully about classifying the failure as // `Internal` rather than `BadRequest`; there is no failure to classify. // // The consequence is not academic: an empty `users.stripe_account_id` // becomes an empty connected-account header on a live charge instead of // an error we can see. assert!(StripeClient::parse_account_id("acct_1A2b3C4d5E6f7G8h").is_ok()); for anything in ["", "cus_123", "not an id", "acct_"] { assert!( StripeClient::parse_account_id(anything).is_ok(), "{anything:?} parses today; if this now fails, the guard became real \ and the test should assert the new contract" ); } } // ── sum_in_currency, the filter behind `get_balance` ── use crate::currency::SettlementCurrency; /// The entries a connected account holding three currencies would carry. fn mixed() -> Vec<(stripe_types::Currency, i64)> { vec![ (SettlementCurrency::Usd.to_stripe(), 1_000), (SettlementCurrency::Gbp.to_stripe(), 2_500), (SettlementCurrency::Usd.to_stripe(), 250), (SettlementCurrency::Eur.to_stripe(), 9_999), ] } #[test] fn sums_every_entry_in_the_wanted_currency() { let entries = mixed(); let total = sum_in_currency( entries.iter().map(|(c, a)| (c, *a)), &SettlementCurrency::Usd.to_stripe(), ); assert_eq!(total, 1_250, "both USD entries, and only those"); } #[test] fn ignores_every_entry_in_another_currency() { let entries = mixed(); for currency in SettlementCurrency::ALL { let total = sum_in_currency(entries.iter().map(|(c, a)| (c, *a)), ¤cy.to_stripe()); let expected = match currency { SettlementCurrency::Usd => 1_250, SettlementCurrency::Gbp => 2_500, SettlementCurrency::Eur => 9_999, _ => 0, }; assert_eq!( total, expected, "{currency} must see its own money and nobody else's" ); } } #[test] fn a_currency_the_account_does_not_hold_is_zero_rather_than_everything() { let entries = mixed(); let total = sum_in_currency( entries.iter().map(|(c, a)| (c, *a)), &SettlementCurrency::Nzd.to_stripe(), ); assert_eq!( total, 0, "an inverted filter would report 13,749 NZD cents the account never held" ); }