feat: Add new Rhai example demonstrating payment flow
- Add a new Rhai example showcasing complete payment flow for company registration. This includes company creation, payment record creation, successful payment processing, status updates, and handling failed and refunded payments. - Add new example demonstrating payment integration in Rhai scripting. This example showcases the usage of various payment status methods and verifies data from the database after processing payments. - Add new examples to Cargo.toml to facilitate building and running the examples. This makes it easier to integrate and test payment functionality using Rhai scripting.
This commit is contained in:
220
heromodels/examples/biz_rhai/payment_flow_example.rs
Normal file
220
heromodels/examples/biz_rhai/payment_flow_example.rs
Normal file
@@ -0,0 +1,220 @@
|
||||
// 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<dyn std::error::Error>> {
|
||||
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<dyn std::error::Error>> {
|
||||
// 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<dyn std::error::Error>> {
|
||||
// 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<bool> = engine.eval(constants_script)?;
|
||||
assert_eq!(results, vec![true, true, true, true]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_company_status_integration() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// 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<rhai::Dynamic> = 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<Company> = db.get_all()?;
|
||||
let company = companies
|
||||
.into_iter()
|
||||
.find(|c| c.name == "Integration Test")
|
||||
.unwrap();
|
||||
assert_eq!(company.status, CompanyStatus::Active);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user