fake_stripe_client.rs

  1use std::sync::Arc;
  2
  3use anyhow::{Result, anyhow};
  4use async_trait::async_trait;
  5use collections::HashMap;
  6use parking_lot::Mutex;
  7use uuid::Uuid;
  8
  9use crate::stripe_client::{
 10    CreateCustomerParams, StripeClient, StripeCreateMeterEventParams, StripeCustomer,
 11    StripeCustomerId, StripeMeter, StripeMeterId, StripePrice, StripePriceId, StripeSubscription,
 12    StripeSubscriptionId, UpdateSubscriptionParams,
 13};
 14
 15#[derive(Debug, Clone)]
 16pub struct StripeCreateMeterEventCall {
 17    pub identifier: Arc<str>,
 18    pub event_name: Arc<str>,
 19    pub value: u64,
 20    pub stripe_customer_id: StripeCustomerId,
 21    pub timestamp: Option<i64>,
 22}
 23
 24pub struct FakeStripeClient {
 25    pub customers: Arc<Mutex<HashMap<StripeCustomerId, StripeCustomer>>>,
 26    pub subscriptions: Arc<Mutex<HashMap<StripeSubscriptionId, StripeSubscription>>>,
 27    pub update_subscription_calls:
 28        Arc<Mutex<Vec<(StripeSubscriptionId, UpdateSubscriptionParams)>>>,
 29    pub prices: Arc<Mutex<HashMap<StripePriceId, StripePrice>>>,
 30    pub meters: Arc<Mutex<HashMap<StripeMeterId, StripeMeter>>>,
 31    pub create_meter_event_calls: Arc<Mutex<Vec<StripeCreateMeterEventCall>>>,
 32}
 33
 34impl FakeStripeClient {
 35    pub fn new() -> Self {
 36        Self {
 37            customers: Arc::new(Mutex::new(HashMap::default())),
 38            subscriptions: Arc::new(Mutex::new(HashMap::default())),
 39            update_subscription_calls: Arc::new(Mutex::new(Vec::new())),
 40            prices: Arc::new(Mutex::new(HashMap::default())),
 41            meters: Arc::new(Mutex::new(HashMap::default())),
 42            create_meter_event_calls: Arc::new(Mutex::new(Vec::new())),
 43        }
 44    }
 45}
 46
 47#[async_trait]
 48impl StripeClient for FakeStripeClient {
 49    async fn list_customers_by_email(&self, email: &str) -> Result<Vec<StripeCustomer>> {
 50        Ok(self
 51            .customers
 52            .lock()
 53            .values()
 54            .filter(|customer| customer.email.as_deref() == Some(email))
 55            .cloned()
 56            .collect())
 57    }
 58
 59    async fn create_customer(&self, params: CreateCustomerParams<'_>) -> Result<StripeCustomer> {
 60        let customer = StripeCustomer {
 61            id: StripeCustomerId(format!("cus_{}", Uuid::new_v4()).into()),
 62            email: params.email.map(|email| email.to_string()),
 63        };
 64
 65        self.customers
 66            .lock()
 67            .insert(customer.id.clone(), customer.clone());
 68
 69        Ok(customer)
 70    }
 71
 72    async fn get_subscription(
 73        &self,
 74        subscription_id: &StripeSubscriptionId,
 75    ) -> Result<StripeSubscription> {
 76        self.subscriptions
 77            .lock()
 78            .get(subscription_id)
 79            .cloned()
 80            .ok_or_else(|| anyhow!("no subscription found for {subscription_id:?}"))
 81    }
 82
 83    async fn update_subscription(
 84        &self,
 85        subscription_id: &StripeSubscriptionId,
 86        params: UpdateSubscriptionParams,
 87    ) -> Result<()> {
 88        let subscription = self.get_subscription(subscription_id).await?;
 89
 90        self.update_subscription_calls
 91            .lock()
 92            .push((subscription.id, params));
 93
 94        Ok(())
 95    }
 96
 97    async fn list_prices(&self) -> Result<Vec<StripePrice>> {
 98        let prices = self.prices.lock().values().cloned().collect();
 99
100        Ok(prices)
101    }
102
103    async fn list_meters(&self) -> Result<Vec<StripeMeter>> {
104        let meters = self.meters.lock().values().cloned().collect();
105
106        Ok(meters)
107    }
108
109    async fn create_meter_event(&self, params: StripeCreateMeterEventParams<'_>) -> Result<()> {
110        self.create_meter_event_calls
111            .lock()
112            .push(StripeCreateMeterEventCall {
113                identifier: params.identifier.into(),
114                event_name: params.event_name.into(),
115                value: params.payload.value,
116                stripe_customer_id: params.payload.stripe_customer_id.clone(),
117                timestamp: params.timestamp,
118            });
119
120        Ok(())
121    }
122}