// Payment Flow Rhai Example Runner // This example runs the payment_flow.rhai script to demonstrate // the payment integration using Rhai scripting. use heromodels::db::hero::OurDB; use heromodels::models::biz::register_biz_rhai_module; use rhai::Engine; use std::sync::Arc; fn main() -> Result<(), Box> { println!("=== Payment Flow Rhai Example Runner ==="); println!("Running payment flow demonstration using Rhai scripting\n"); // Initialize database let db = Arc::new( OurDB::new("/tmp/payment_flow_rhai_example", true) .map_err(|e| format!("DB Error: {}", e))?, ); // Create and configure Rhai engine let mut engine = Engine::new(); // Register the business models module with the engine register_biz_rhai_module(&mut engine, Arc::clone(&db)); // Add a timestamp function for the Rhai script engine.register_fn("timestamp", || -> i64 { chrono::Utc::now().timestamp() }); // Read and execute the Rhai script let script_path = "examples/biz_rhai/payment_flow.rhai"; match std::fs::read_to_string(script_path) { Ok(script_content) => { println!("Executing Rhai script: {}\n", script_path); match engine.eval::<()>(&script_content) { Ok(_) => { println!("\nāœ… Rhai script executed successfully!"); } Err(e) => { eprintln!("āŒ Error executing Rhai script: {}", e); return Err(Box::new(e)); } } } Err(e) => { eprintln!("āŒ Error reading script file {}: {}", script_path, e); println!("Note: Make sure to run this example from the project root directory."); return Err(Box::new(e)); } } println!("\n=== Example Complete ==="); println!("The payment flow has been successfully demonstrated using Rhai scripting."); println!("This shows how the payment integration can be used in scripted environments."); Ok(()) } #[cfg(test)] mod tests { use super::*; use heromodels::db::Collection; use heromodels::models::biz::{Company, CompanyStatus, Payment, PaymentStatus}; #[test] fn test_rhai_payment_integration() -> Result<(), Box> { // Test that we can create and manipulate payment objects through Rhai let db_config = OurDBConfig { path: "/tmp/test_rhai_payment".to_string(), incremental_mode: true, file_size: None, keysize: None, reset: Some(true), }; let db = Arc::new(OurDB::new(db_config)?); let mut engine = Engine::new(); register_biz_rhai_module(&mut engine, Arc::clone(&db)); // Test creating a company through Rhai let company_script = r#" let company = new_company("Test Company", "TEST-001", 1704067200) .email("test@example.com") .status(CompanyStatusConstants::PendingPayment); company = set_company(company); company.id "#; let company_id: i64 = engine.eval(company_script)?; assert!(company_id > 0); // Test creating a payment through Rhai let payment_script = format!( r#" let payment = new_payment("pi_test_123", {}, "monthly", 100.0, 50.0, 150.0); payment = set_payment(payment); payment.id "#, company_id ); let payment_id: i64 = engine.eval(&payment_script)?; assert!(payment_id > 0); // Test completing payment through Rhai let complete_script = format!( r#" let payment = get_payment_by_id({}); payment = payment.complete_payment("cus_test_123"); payment = set_payment(payment); payment.is_completed() "#, payment_id ); let is_completed: bool = engine.eval(&complete_script)?; assert!(is_completed); // Verify in database let payment: Payment = db.get_by_id(payment_id as u32)?.unwrap(); assert_eq!(payment.status, PaymentStatus::Completed); assert_eq!(payment.stripe_customer_id, Some("cus_test_123".to_string())); Ok(()) } #[test] fn test_payment_status_constants() -> Result<(), Box> { // Test that payment status constants are available in Rhai let db_config = OurDBConfig { path: "/tmp/test_payment_constants".to_string(), incremental_mode: true, file_size: None, keysize: None, reset: Some(true), }; let db = Arc::new(OurDB::new(db_config)?); let mut engine = Engine::new(); register_biz_rhai_module(&mut engine, Arc::clone(&db)); // Test that we can access payment status constants let constants_script = r#" let payment = new_payment("pi_test", 1, "monthly", 100.0, 50.0, 150.0); // Test status transitions payment = payment.status(PaymentStatusConstants::Pending); let is_pending = payment.is_pending(); payment = payment.status(PaymentStatusConstants::Completed); let is_completed = payment.is_completed(); payment = payment.status(PaymentStatusConstants::Failed); let has_failed = payment.has_failed(); payment = payment.status(PaymentStatusConstants::Refunded); let is_refunded = payment.is_refunded(); [is_pending, is_completed, has_failed, is_refunded] "#; let results: Vec = engine.eval(constants_script)?; assert_eq!(results, vec![true, true, true, true]); Ok(()) } #[test] fn test_company_status_integration() -> Result<(), Box> { // Test the integration between company and payment status let db_config = OurDBConfig { path: "/tmp/test_status_integration".to_string(), incremental_mode: true, file_size: None, keysize: None, reset: Some(true), }; let db = Arc::new(OurDB::new(db_config)?); let mut engine = Engine::new(); register_biz_rhai_module(&mut engine, Arc::clone(&db)); let integration_script = r#" // Create company (defaults to PendingPayment) let company = new_company("Integration Test", "INT-001", 1704067200); company = set_company(company); // Create payment let payment = new_payment("pi_int_test", company.id, "yearly", 500.0, 99.0, 1688.0); payment = set_payment(payment); // Complete payment payment = payment.complete_payment("cus_int_test"); payment = set_payment(payment); // Update company to active company = company.status(CompanyStatusConstants::Active); company = set_company(company); [payment.is_completed(), company.status] "#; let results: Vec = engine.eval(integration_script)?; // Check that payment is completed assert!(results[0].as_bool().unwrap()); // Check that company status is Active (we can't directly compare enum in Rhai result) // So we'll verify by retrieving from database let companies: Vec = db.get_all()?; let company = companies .into_iter() .find(|c| c.name == "Integration Test") .unwrap(); assert_eq!(company.status, CompanyStatus::Active); Ok(()) } }