collab: Fully move StripeBilling
over to using StripeClient
(#31722)
This PR moves over the last method on `StripeBilling` to use the `StripeClient` trait, allowing us to fully mock out Stripe behaviors for `StripeBilling` in tests. Release Notes: - N/A
This commit is contained in:
parent
406d975f39
commit
c7047d5f0a
7 changed files with 273 additions and 50 deletions
|
@ -2,6 +2,7 @@ use std::sync::Arc;
|
|||
|
||||
use anyhow::{Result, anyhow};
|
||||
use async_trait::async_trait;
|
||||
use chrono::{Duration, Utc};
|
||||
use collections::HashMap;
|
||||
use parking_lot::Mutex;
|
||||
use uuid::Uuid;
|
||||
|
@ -10,9 +11,10 @@ use crate::stripe_client::{
|
|||
CreateCustomerParams, StripeCheckoutSession, StripeCheckoutSessionMode,
|
||||
StripeCheckoutSessionPaymentMethodCollection, StripeClient,
|
||||
StripeCreateCheckoutSessionLineItems, StripeCreateCheckoutSessionParams,
|
||||
StripeCreateCheckoutSessionSubscriptionData, StripeCreateMeterEventParams, StripeCustomer,
|
||||
StripeCustomerId, StripeMeter, StripeMeterId, StripePrice, StripePriceId, StripeSubscription,
|
||||
StripeSubscriptionId, UpdateSubscriptionParams,
|
||||
StripeCreateCheckoutSessionSubscriptionData, StripeCreateMeterEventParams,
|
||||
StripeCreateSubscriptionParams, StripeCustomer, StripeCustomerId, StripeMeter, StripeMeterId,
|
||||
StripePrice, StripePriceId, StripeSubscription, StripeSubscriptionId, StripeSubscriptionItem,
|
||||
StripeSubscriptionItemId, UpdateSubscriptionParams,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -85,6 +87,21 @@ impl StripeClient for FakeStripeClient {
|
|||
Ok(customer)
|
||||
}
|
||||
|
||||
async fn list_subscriptions_for_customer(
|
||||
&self,
|
||||
customer_id: &StripeCustomerId,
|
||||
) -> Result<Vec<StripeSubscription>> {
|
||||
let subscriptions = self
|
||||
.subscriptions
|
||||
.lock()
|
||||
.values()
|
||||
.filter(|subscription| subscription.customer == *customer_id)
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
Ok(subscriptions)
|
||||
}
|
||||
|
||||
async fn get_subscription(
|
||||
&self,
|
||||
subscription_id: &StripeSubscriptionId,
|
||||
|
@ -96,6 +113,37 @@ impl StripeClient for FakeStripeClient {
|
|||
.ok_or_else(|| anyhow!("no subscription found for {subscription_id:?}"))
|
||||
}
|
||||
|
||||
async fn create_subscription(
|
||||
&self,
|
||||
params: StripeCreateSubscriptionParams,
|
||||
) -> Result<StripeSubscription> {
|
||||
let now = Utc::now();
|
||||
|
||||
let subscription = StripeSubscription {
|
||||
id: StripeSubscriptionId(format!("sub_{}", Uuid::new_v4()).into()),
|
||||
customer: params.customer,
|
||||
status: stripe::SubscriptionStatus::Active,
|
||||
current_period_start: now.timestamp(),
|
||||
current_period_end: (now + Duration::days(30)).timestamp(),
|
||||
items: params
|
||||
.items
|
||||
.into_iter()
|
||||
.map(|item| StripeSubscriptionItem {
|
||||
id: StripeSubscriptionItemId(format!("si_{}", Uuid::new_v4()).into()),
|
||||
price: item
|
||||
.price
|
||||
.and_then(|price_id| self.prices.lock().get(&price_id).cloned()),
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
|
||||
self.subscriptions
|
||||
.lock()
|
||||
.insert(subscription.id.clone(), subscription.clone());
|
||||
|
||||
Ok(subscription)
|
||||
}
|
||||
|
||||
async fn update_subscription(
|
||||
&self,
|
||||
subscription_id: &StripeSubscriptionId,
|
||||
|
|
|
@ -20,10 +20,11 @@ use crate::stripe_client::{
|
|||
CreateCustomerParams, StripeCheckoutSession, StripeCheckoutSessionMode,
|
||||
StripeCheckoutSessionPaymentMethodCollection, StripeClient,
|
||||
StripeCreateCheckoutSessionLineItems, StripeCreateCheckoutSessionParams,
|
||||
StripeCreateCheckoutSessionSubscriptionData, StripeCreateMeterEventParams, StripeCustomer,
|
||||
StripeCustomerId, StripeMeter, StripePrice, StripePriceId, StripePriceRecurring,
|
||||
StripeSubscription, StripeSubscriptionId, StripeSubscriptionItem, StripeSubscriptionItemId,
|
||||
StripeSubscriptionTrialSettings, StripeSubscriptionTrialSettingsEndBehavior,
|
||||
StripeCreateCheckoutSessionSubscriptionData, StripeCreateMeterEventParams,
|
||||
StripeCreateSubscriptionParams, StripeCustomer, StripeCustomerId, StripeMeter, StripePrice,
|
||||
StripePriceId, StripePriceRecurring, StripeSubscription, StripeSubscriptionId,
|
||||
StripeSubscriptionItem, StripeSubscriptionItemId, StripeSubscriptionTrialSettings,
|
||||
StripeSubscriptionTrialSettingsEndBehavior,
|
||||
StripeSubscriptionTrialSettingsEndBehaviorMissingPaymentMethod, UpdateSubscriptionParams,
|
||||
};
|
||||
|
||||
|
@ -69,6 +70,29 @@ impl StripeClient for RealStripeClient {
|
|||
Ok(StripeCustomer::from(customer))
|
||||
}
|
||||
|
||||
async fn list_subscriptions_for_customer(
|
||||
&self,
|
||||
customer_id: &StripeCustomerId,
|
||||
) -> Result<Vec<StripeSubscription>> {
|
||||
let customer_id = customer_id.try_into()?;
|
||||
|
||||
let subscriptions = stripe::Subscription::list(
|
||||
&self.client,
|
||||
&stripe::ListSubscriptions {
|
||||
customer: Some(customer_id),
|
||||
status: None,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(subscriptions
|
||||
.data
|
||||
.into_iter()
|
||||
.map(StripeSubscription::from)
|
||||
.collect())
|
||||
}
|
||||
|
||||
async fn get_subscription(
|
||||
&self,
|
||||
subscription_id: &StripeSubscriptionId,
|
||||
|
@ -80,6 +104,30 @@ impl StripeClient for RealStripeClient {
|
|||
Ok(StripeSubscription::from(subscription))
|
||||
}
|
||||
|
||||
async fn create_subscription(
|
||||
&self,
|
||||
params: StripeCreateSubscriptionParams,
|
||||
) -> Result<StripeSubscription> {
|
||||
let customer_id = params.customer.try_into()?;
|
||||
|
||||
let mut create_subscription = stripe::CreateSubscription::new(customer_id);
|
||||
create_subscription.items = Some(
|
||||
params
|
||||
.items
|
||||
.into_iter()
|
||||
.map(|item| stripe::CreateSubscriptionItems {
|
||||
price: item.price.map(|price| price.to_string()),
|
||||
quantity: item.quantity,
|
||||
..Default::default()
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
|
||||
let subscription = Subscription::create(&self.client, create_subscription).await?;
|
||||
|
||||
Ok(StripeSubscription::from(subscription))
|
||||
}
|
||||
|
||||
async fn update_subscription(
|
||||
&self,
|
||||
subscription_id: &StripeSubscriptionId,
|
||||
|
@ -220,6 +268,10 @@ impl From<Subscription> for StripeSubscription {
|
|||
fn from(value: Subscription) -> Self {
|
||||
Self {
|
||||
id: value.id.into(),
|
||||
customer: value.customer.id().into(),
|
||||
status: value.status,
|
||||
current_period_start: value.current_period_start,
|
||||
current_period_end: value.current_period_end,
|
||||
items: value.items.data.into_iter().map(Into::into).collect(),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue