db/herodb/src/_archive/tests/db_integration_test.rs
2025-04-05 10:17:23 +02:00

298 lines
8.9 KiB
Rust

//! Integration tests for the zaz database module
use crate::core::{DB, DBBuilder, SledDBResult, Storable, SledModel, SledDB};
use crate::zaz::models::user::User;
use crate::zaz::models::company::{Company, BusinessType, CompanyStatus};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::Path;
use tempfile::tempdir;
use std::fmt::{Display, Formatter};
/// Test the basic database functionality
#[test]
fn test_basic_database_operations() {
match run_comprehensive_test() {
Ok(_) => println!("All tests passed successfully!"),
Err(e) => panic!("Error running tests: {}", e),
}
}
fn run_comprehensive_test() -> Result<(), Box<dyn std::error::Error>> {
// Create a temporary directory for testing
let temp_dir = tempdir()?;
println!("Using temporary directory: {:?}", temp_dir.path());
println!("\n--- Testing User operations ---");
test_user_operations(temp_dir.path())?;
println!("\n--- Testing Company operations ---");
test_company_operations(temp_dir.path())?;
println!("\n--- Testing Transaction Simulation ---");
test_transaction_simulation(temp_dir.path())?;
// Clean up
drop(temp_dir);
println!("All comprehensive tests completed successfully!");
Ok(())
}
fn test_user_operations(base_path: &Path) -> Result<(), Box<dyn std::error::Error>> {
// Open the user database
let db = SledDB::<User>::open(base_path.join("users"))?;
println!("Opened user database at: {:?}", base_path.join("users"));
// Create a test user
let user = User::new(
100,
"Test User".to_string(),
"test@example.com".to_string(),
"password123".to_string(),
"Test Company".to_string(),
"Admin".to_string(),
);
// Insert the user
db.insert(&user)?;
println!("Inserted user: {}", user.name);
// Retrieve the user
let retrieved_user = db.get(&user.id.to_string())?;
println!("Retrieved user: {}", retrieved_user.name);
assert_eq!(user.name, retrieved_user.name);
assert_eq!(user.email, retrieved_user.email);
// Update the user
let updated_user = User::new(
100,
"Updated User".to_string(),
"updated@example.com".to_string(),
"newpassword".to_string(),
"New Company".to_string(),
"SuperAdmin".to_string(),
);
db.insert(&updated_user)?;
println!("Updated user: {}", updated_user.name);
// Retrieve the updated user
let retrieved_user = db.get(&user.id.to_string())?;
println!("Retrieved updated user: {}", retrieved_user.name);
assert_eq!(updated_user.name, retrieved_user.name);
assert_eq!(updated_user.email, retrieved_user.email);
// Delete the user
db.delete(&user.id.to_string())?;
println!("Deleted user: {}", user.name);
// Try to retrieve the deleted user (should fail)
let result = db.get(&user.id.to_string());
assert!(result.is_err(), "User should be deleted");
println!("Verified user was deleted");
Ok(())
}
fn test_company_operations(base_path: &Path) -> Result<(), Box<dyn std::error::Error>> {
// Open the company database
let db = SledDB::<Company>::open(base_path.join("companies"))?;
println!("Opened company database at: {:?}", base_path.join("companies"));
// Create a test company
let company = Company::new(
100,
"Test Corp".to_string(),
"TEST123".to_string(),
Utc::now(),
"12-31".to_string(),
"test@corp.com".to_string(),
"123-456-7890".to_string(),
"www.testcorp.com".to_string(),
"123 Test St".to_string(),
BusinessType::new(BusinessType::GLOBAL.to_string())
.unwrap_or_else(|e| {
eprintln!("Warning: {}", e);
BusinessType::new_unchecked(BusinessType::GLOBAL.to_string())
}),
"Technology".to_string(),
"A test company".to_string(),
CompanyStatus::Active,
);
// Insert the company
db.insert(&company)?;
println!("Inserted company: {}", company.name);
// Retrieve the company
let retrieved_company = db.get(&company.id.to_string())?;
println!("Retrieved company: {}", retrieved_company.name);
assert_eq!(company.name, retrieved_company.name);
// List all companies
let companies = db.list()?;
println!("Found {} companies", companies.len());
assert_eq!(companies.len(), 1);
// Delete the company
db.delete(&company.id.to_string())?;
println!("Deleted company: {}", company.name);
// List companies again (should be empty)
let companies = db.list()?;
assert_eq!(companies.len(), 0);
println!("Verified company was deleted");
Ok(())
}
fn test_transaction_simulation(base_path: &Path) -> Result<(), Box<dyn std::error::Error>> {
// Create a DB instance with User model registered
let mut db = DB::new(base_path.join("transaction"))?;
db.register::<User>()?;
println!("Created DB with User model registered at: {:?}", base_path.join("transaction"));
// Add a user outside of transaction
let user = User::new(
200,
"Transaction Test".to_string(),
"tx@example.com".to_string(),
"password".to_string(),
"TX Corp".to_string(),
"User".to_string(),
);
// Add the user without a transaction
db.set(&user)?;
println!("Added initial user: {}", user.name);
// Begin a transaction
db.begin_transaction()?;
println!("Transaction started");
// Update user in transaction
let updated_user = User::new(
200,
"Updated in TX".to_string(),
"updated@example.com".to_string(),
"newpass".to_string(),
"New Corp".to_string(),
"Admin".to_string(),
);
db.set(&updated_user)?;
println!("Updated user in transaction");
// Add new user in transaction
let new_user = User::new(
201,
"New in TX".to_string(),
"new@example.com".to_string(),
"password".to_string(),
"New Corp".to_string(),
"User".to_string(),
);
db.set(&new_user)?;
println!("Added new user in transaction");
// Verify transaction changes are visible within transaction
let tx_user: User = db.get(&user.id.to_string())?;
assert_eq!(tx_user.name, "Updated in TX");
println!("Verified transaction changes are visible");
// Commit the transaction
db.commit_transaction()?;
println!("Transaction committed");
// Verify changes persisted after commit
let committed_user: User = db.get(&user.id.to_string())?;
assert_eq!(committed_user.name, "Updated in TX");
println!("Verified changes persisted after commit");
// Test transaction rollback
// Begin another transaction
db.begin_transaction()?;
println!("New transaction started");
// Make changes that will be rolled back
let rollback_user = User::new(
200,
"Will Be Rolled Back".to_string(),
"rollback@example.com".to_string(),
"temppass".to_string(),
"Temp Corp".to_string(),
"TempAdmin".to_string(),
);
db.set(&rollback_user)?;
println!("Updated user in transaction that will be rolled back");
// Rollback the transaction
db.rollback_transaction()?;
println!("Transaction rolled back");
// Verify original data is intact
let after_rollback: User = db.get(&user.id.to_string())?;
assert_eq!(after_rollback.name, "Updated in TX");
println!("Verified data is intact after rollback: {}", after_rollback.name);
Ok(())
}
#[test]
fn test_simple_db() {
// A simpler test that uses a basic DB setup
// Test model
#[derive(Debug, Clone, Serialize, Deserialize)]
struct User {
id: u32,
name: String,
email: String,
}
impl User {
fn new(id: u32, name: String, email: String) -> Self {
Self { id, name, email }
}
}
impl Storable for User {}
impl SledModel for User {
fn get_id(&self) -> String {
self.id.to_string()
}
fn db_prefix() -> &'static str {
"test_simple_user"
}
}
// Create a temporary directory for the test
let dir = tempdir().expect("Failed to create temp dir");
// Create a DB with the builder
let db = DBBuilder::new(dir.path())
.register_model::<User>()
.build()
.expect("Failed to build DB");
// Create a test user
let user = User::new(1, "Simple Test User".to_string(), "simple@example.com".to_string());
// Set the user
db.set(&user).expect("Failed to set user");
// Get the user
let retrieved: User = db.get(&user.id.to_string()).expect("Failed to get user");
// Check that it matches
assert_eq!(user.name, retrieved.name);
assert_eq!(user.email, retrieved.email);
println!("Simple DB test passed!");
}