1use std::sync::Arc;
2
3use pretty_assertions::assert_eq;
4
5use crate::stripe_billing::StripeBilling;
6use crate::stripe_client::{FakeStripeClient, StripePrice, StripePriceId, StripePriceRecurring};
7
8fn make_stripe_billing() -> (StripeBilling, Arc<FakeStripeClient>) {
9 let stripe_client = Arc::new(FakeStripeClient::new());
10 let stripe_billing = StripeBilling::test(stripe_client.clone());
11
12 (stripe_billing, stripe_client)
13}
14
15#[gpui::test]
16async fn test_initialize() {
17 let (stripe_billing, stripe_client) = make_stripe_billing();
18
19 // Add test prices
20 let price1 = StripePrice {
21 id: StripePriceId("price_1".into()),
22 unit_amount: Some(1_000),
23 lookup_key: Some("zed-pro".to_string()),
24 recurring: None,
25 };
26 let price2 = StripePrice {
27 id: StripePriceId("price_2".into()),
28 unit_amount: Some(0),
29 lookup_key: Some("zed-free".to_string()),
30 recurring: None,
31 };
32 let price3 = StripePrice {
33 id: StripePriceId("price_3".into()),
34 unit_amount: Some(500),
35 lookup_key: None,
36 recurring: Some(StripePriceRecurring {
37 meter: Some("meter_1".to_string()),
38 }),
39 };
40 stripe_client
41 .prices
42 .lock()
43 .insert(price1.id.clone(), price1);
44 stripe_client
45 .prices
46 .lock()
47 .insert(price2.id.clone(), price2);
48 stripe_client
49 .prices
50 .lock()
51 .insert(price3.id.clone(), price3);
52
53 // Initialize the billing system
54 stripe_billing.initialize().await.unwrap();
55
56 // Verify that prices can be found by lookup key
57 let zed_pro_price_id = stripe_billing.zed_pro_price_id().await.unwrap();
58 assert_eq!(zed_pro_price_id.to_string(), "price_1");
59
60 let zed_free_price_id = stripe_billing.zed_free_price_id().await.unwrap();
61 assert_eq!(zed_free_price_id.to_string(), "price_2");
62
63 // Verify that a price can be found by lookup key
64 let zed_pro_price = stripe_billing
65 .find_price_by_lookup_key("zed-pro")
66 .await
67 .unwrap();
68 assert_eq!(zed_pro_price.id.to_string(), "price_1");
69 assert_eq!(zed_pro_price.unit_amount, Some(1_000));
70
71 // Verify that finding a non-existent lookup key returns an error
72 let result = stripe_billing
73 .find_price_by_lookup_key("non-existent")
74 .await;
75 assert!(result.is_err());
76}
77
78#[gpui::test]
79async fn test_find_or_create_customer_by_email() {
80 let (stripe_billing, stripe_client) = make_stripe_billing();
81
82 // Create a customer with an email that doesn't yet correspond to a customer.
83 {
84 let email = "user@example.com";
85
86 let customer_id = stripe_billing
87 .find_or_create_customer_by_email(Some(email))
88 .await
89 .unwrap();
90
91 let customer = stripe_client
92 .customers
93 .lock()
94 .get(&customer_id)
95 .unwrap()
96 .clone();
97 assert_eq!(customer.email.as_deref(), Some(email));
98 }
99
100 // Create a customer with an email that corresponds to an existing customer.
101 {
102 let email = "user2@example.com";
103
104 let existing_customer_id = stripe_billing
105 .find_or_create_customer_by_email(Some(email))
106 .await
107 .unwrap();
108
109 let customer_id = stripe_billing
110 .find_or_create_customer_by_email(Some(email))
111 .await
112 .unwrap();
113 assert_eq!(customer_id, existing_customer_id);
114
115 let customer = stripe_client
116 .customers
117 .lock()
118 .get(&customer_id)
119 .unwrap()
120 .clone();
121 assert_eq!(customer.email.as_deref(), Some(email));
122 }
123}