144 lines
6.5 KiB
Rust
144 lines
6.5 KiB
Rust
#[cfg(test)]
|
|
mod tests {
|
|
use threefold_marketplace::services::farmer::FarmerService;
|
|
use threefold_marketplace::services::user_persistence::UserPersistence;
|
|
use threefold_marketplace::models::user::NodeStakingOptions;
|
|
use rust_decimal::Decimal;
|
|
|
|
#[test]
|
|
fn test_staking_end_to_end_flow() {
|
|
// Test the complete staking flow for user1
|
|
let user_email = "user1@example.com";
|
|
let farmer_service = FarmerService::builder().build().unwrap();
|
|
|
|
// Clean up any existing staking data first
|
|
let user_data = UserPersistence::load_user_data(user_email);
|
|
assert!(user_data.is_some(), "User1 data should exist");
|
|
|
|
let user_data = user_data.unwrap();
|
|
|
|
// Unstake from all nodes to start with a clean state
|
|
for node in &user_data.nodes {
|
|
if let Some(staking_options) = &node.staking_options {
|
|
if staking_options.staking_enabled {
|
|
let _ = farmer_service.unstake_from_node(user_email, &node.id);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Reload user data after cleanup
|
|
let user_data = UserPersistence::load_user_data(user_email).unwrap();
|
|
println!("Initial wallet balance: {}", user_data.wallet_balance_usd);
|
|
println!("Number of nodes: {}", user_data.nodes.len());
|
|
|
|
// Verify user has sufficient balance (should be 11000 TFP)
|
|
assert!(user_data.wallet_balance_usd >= Decimal::from(100), "User should have at least 100 TFP");
|
|
|
|
// Verify user has nodes to stake on
|
|
assert!(!user_data.nodes.is_empty(), "User should have nodes");
|
|
|
|
let first_node = &user_data.nodes[0];
|
|
println!("First node ID: {}", first_node.id);
|
|
println!("First node name: {}", first_node.name);
|
|
|
|
// Test staking 100 TFP on the first node
|
|
let staking_options = NodeStakingOptions {
|
|
staking_enabled: true,
|
|
staked_amount: Decimal::from(100),
|
|
staking_start_date: None, // Will be set by the service
|
|
staking_period_months: 12,
|
|
early_withdrawal_allowed: true,
|
|
early_withdrawal_penalty_percent: 5.0,
|
|
};
|
|
|
|
// Perform staking
|
|
let stake_result = farmer_service.stake_on_node(user_email, &first_node.id, staking_options);
|
|
|
|
match stake_result {
|
|
Ok(()) => {
|
|
println!("✅ Staking successful!");
|
|
|
|
// Verify the staking was applied
|
|
let updated_data = UserPersistence::load_user_data(user_email).unwrap();
|
|
|
|
// Check wallet balance decreased
|
|
let expected_balance = user_data.wallet_balance_usd - Decimal::from(100);
|
|
assert_eq!(updated_data.wallet_balance_usd, expected_balance,
|
|
"Wallet balance should decrease by staked amount");
|
|
|
|
// Check node has staking options
|
|
let updated_node = updated_data.nodes.iter()
|
|
.find(|n| n.id == first_node.id)
|
|
.expect("Node should still exist");
|
|
|
|
assert!(updated_node.staking_options.is_some(), "Node should have staking options");
|
|
let node_staking = updated_node.staking_options.as_ref().unwrap();
|
|
assert!(node_staking.staking_enabled, "Staking should be enabled");
|
|
assert_eq!(node_staking.staked_amount, Decimal::from(100), "Staked amount should be 100");
|
|
|
|
println!("✅ All staking verifications passed!");
|
|
|
|
// Test getting staking statistics
|
|
let stats = farmer_service.get_staking_statistics(user_email);
|
|
assert_eq!(stats.total_staked_amount, Decimal::from(100), "Total staked should be 100");
|
|
assert_eq!(stats.staked_nodes_count, 1, "Should have 1 staked node");
|
|
|
|
println!("✅ Staking statistics correct!");
|
|
|
|
// Test unstaking
|
|
let unstake_result = farmer_service.unstake_from_node(user_email, &first_node.id);
|
|
match unstake_result {
|
|
Ok(returned_amount) => {
|
|
println!("✅ Unstaking successful! Returned: {} TFP", returned_amount);
|
|
|
|
// Verify unstaking
|
|
let final_data = UserPersistence::load_user_data(user_email).unwrap();
|
|
let final_node = final_data.nodes.iter()
|
|
.find(|n| n.id == first_node.id)
|
|
.expect("Node should still exist");
|
|
|
|
assert!(final_node.staking_options.is_none(), "Node should not have staking options after unstaking");
|
|
|
|
println!("✅ Complete staking flow test passed!");
|
|
}
|
|
Err(e) => {
|
|
println!("❌ Unstaking failed: {}", e);
|
|
panic!("Unstaking should succeed");
|
|
}
|
|
}
|
|
}
|
|
Err(e) => {
|
|
println!("❌ Staking failed: {}", e);
|
|
panic!("Staking should succeed with sufficient balance");
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_insufficient_balance_staking() {
|
|
let user_email = "user1@example.com";
|
|
let farmer_service = FarmerService::builder().build().unwrap();
|
|
|
|
let user_data = UserPersistence::load_user_data(user_email).unwrap();
|
|
let first_node = &user_data.nodes[0];
|
|
|
|
// Try to stake more than available balance
|
|
let excessive_amount = user_data.wallet_balance_usd + Decimal::from(1000);
|
|
let staking_options = NodeStakingOptions {
|
|
staking_enabled: true,
|
|
staked_amount: excessive_amount,
|
|
staking_start_date: None,
|
|
staking_period_months: 12,
|
|
early_withdrawal_allowed: true,
|
|
early_withdrawal_penalty_percent: 5.0,
|
|
};
|
|
|
|
let result = farmer_service.stake_on_node(user_email, &first_node.id, staking_options);
|
|
assert!(result.is_err(), "Staking should fail with insufficient balance");
|
|
|
|
let error_msg = result.unwrap_err();
|
|
assert!(error_msg.contains("Insufficient balance"), "Error should mention insufficient balance");
|
|
|
|
println!("✅ Insufficient balance test passed!");
|
|
}
|
|
} |