use flowglad::types::customer::{CreateCustomer, UpdateCustomer};
use flowglad::{Client, Config};
use once_cell::sync::Lazy;
static TEST_CLIENT: Lazy<Client> = Lazy::new(|| {
let _ = dotenvy::dotenv();
let api_key = std::env::var("FLOWGLAD_API_KEY")
.expect("FLOWGLAD_API_KEY environment variable must be set to run integration tests");
let config = Config::new(api_key);
Client::new(config).expect("Failed to create test client")
});
fn unique_email(prefix: &str) -> String {
use std::time::{SystemTime, UNIX_EPOCH};
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
format!("{}+{}@flowglad-test.com", prefix, timestamp)
}
fn unique_name(prefix: &str) -> String {
use std::time::{SystemTime, UNIX_EPOCH};
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
format!("{} {}", prefix, timestamp)
}
fn unique_external_id(prefix: &str) -> String {
use std::time::{SystemTime, UNIX_EPOCH};
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
format!("{}_{}", prefix, timestamp)
}
#[tokio::test]
async fn test_create_customer() {
let external_id = unique_external_id("test_create");
let email = unique_email("create");
let name = unique_name("Create Test");
let result = TEST_CLIENT
.customers()
.create(CreateCustomer::new(&external_id, &name).email(&email))
.await;
assert!(
result.is_ok(),
"Failed to create customer: {:?}",
result.err()
);
let customer = result.unwrap();
assert_eq!(customer.email.as_deref(), Some(email.as_str()));
assert_eq!(customer.name.as_deref(), Some(name.as_str()));
assert!(!customer.id.as_str().is_empty());
println!("✓ Created customer: {} ({})", customer.id, email);
}
#[tokio::test]
async fn test_create_customer_with_metadata() {
let external_id = unique_external_id("test_metadata");
let email = unique_email("metadata");
let result = TEST_CLIENT
.customers()
.create(
CreateCustomer::new(&external_id, "Metadata Test")
.email(&email)
.metadata("test_key", serde_json::json!("test_value"))
.metadata("tier", serde_json::json!(3)),
)
.await;
assert!(
result.is_ok(),
"Failed to create customer: {:?}",
result.err()
);
let customer = result.unwrap();
assert!(!customer.id.as_str().is_empty());
println!("✓ Created customer with metadata: {}", customer.id);
}
#[tokio::test]
async fn test_get_customer() {
let external_id = unique_external_id("test_get");
let email = unique_email("get");
let created = TEST_CLIENT
.customers()
.create(CreateCustomer::new(&external_id, "Get Test").email(&email))
.await
.expect("Failed to create customer");
let result = TEST_CLIENT.customers().get(&external_id).await;
assert!(result.is_ok(), "Failed to get customer: {:?}", result.err());
let retrieved = result.unwrap();
assert_eq!(created.id, retrieved.id);
assert_eq!(created.email, retrieved.email);
assert_eq!(created.name, retrieved.name);
println!("✓ Retrieved customer: {}", retrieved.id);
}
#[tokio::test]
async fn test_get_nonexistent_customer() {
let fake_external_id = "nonexistent_external_id_12345";
let result = TEST_CLIENT.customers().get(fake_external_id).await;
assert!(result.is_err(), "Expected error for nonexistent customer");
let error = result.unwrap_err();
assert!(
error.to_string().contains("404")
|| error.to_string().contains("not found")
|| error.to_string().contains("NOT_FOUND"),
"Expected 404 error, got: {}",
error
);
println!("✓ Correctly handled nonexistent customer");
}
#[tokio::test]
async fn test_list_customers() {
let external_id = unique_external_id("test_list");
let email = unique_email("list");
let _ = TEST_CLIENT
.customers()
.create(CreateCustomer::new(&external_id, "List Test").email(&email))
.await
.expect("Failed to create customer");
let result = TEST_CLIENT.customers().list().await;
assert!(
result.is_ok(),
"Failed to list customers: {:?}",
result.err()
);
let list = result.unwrap();
assert!(!list.data.is_empty(), "Expected at least one customer");
assert!(!list.is_empty());
assert!(list.len() > 0);
println!("✓ Listed {} customers", list.len());
}
#[tokio::test]
async fn test_update_customer() {
let external_id = unique_external_id("test_update");
let email = unique_email("update");
let created = TEST_CLIENT
.customers()
.create(CreateCustomer::new(&external_id, "Original Name").email(&email))
.await
.expect("Failed to create customer");
let new_email = unique_email("updated");
let result = TEST_CLIENT
.customers()
.update(
&external_id,
UpdateCustomer::new()
.email(&new_email)
.name("Updated Name")
.phone("+1-555-9999"),
)
.await;
assert!(
result.is_ok(),
"Failed to update customer: {:?}",
result.err()
);
let updated = result.unwrap();
assert_eq!(updated.id, created.id);
assert_eq!(updated.email.as_deref(), Some(new_email.as_str()));
assert_eq!(updated.name.as_deref(), Some("Updated Name"));
println!("✓ Updated customer: {}", updated.id);
}
#[tokio::test]
async fn test_get_billing_details() {
let external_id = unique_external_id("test_billing");
let email = unique_email("billing");
let created = TEST_CLIENT
.customers()
.create(CreateCustomer::new(&external_id, "Billing Test").email(&email))
.await
.expect("Failed to create customer");
let result = TEST_CLIENT.customers().get_billing(&external_id).await;
assert!(
result.is_ok(),
"Failed to get billing details: {:?}",
result.err()
);
let billing = result.unwrap();
assert_eq!(billing.customer.id, created.id);
assert!(!billing.subscriptions.is_empty() || !billing.current_subscriptions.is_empty());
println!(
"✓ Retrieved billing details for customer: {}",
billing.customer.id
);
}
#[tokio::test]
async fn test_customer_with_phone() {
let external_id = unique_external_id("test_phone");
let email = unique_email("phone");
let result = TEST_CLIENT
.customers()
.create(
CreateCustomer::new(&external_id, "Phone Test")
.email(&email)
.phone("+1-555-1234"),
)
.await;
assert!(
result.is_ok(),
"Failed to create customer: {:?}",
result.err()
);
let customer = result.unwrap();
assert!(!customer.id.as_str().is_empty());
println!("✓ Created customer with phone: {}", customer.id);
}