298 lines
8.9 KiB
Rust
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!");
|
|
}
|