diff --git a/Cargo.toml b/Cargo.toml index 6cf3237..37bf764 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,9 @@ members = [ "orchestrator", "cli", "scenarios", + + "testutils", + "integration_tests", ] default-members = [ @@ -27,6 +30,7 @@ default-members = [ "data_migration", "reporting", "orchestrator", + ] resolver = "2" diff --git a/bill_payments/Cargo.toml b/bill_payments/Cargo.toml index eb68d66..ec3dbff 100644 --- a/bill_payments/Cargo.toml +++ b/bill_payments/Cargo.toml @@ -13,5 +13,6 @@ remitwise-common = { path = "../remitwise-common" } [dev-dependencies] proptest = "1.10.0" soroban-sdk = { version = "21.0.0", features = ["testutils"] } +testutils = { path = "../testutils" } diff --git a/bill_payments/src/test.rs b/bill_payments/src/test.rs index f360f4f..e36bae8 100644 --- a/bill_payments/src/test.rs +++ b/bill_payments/src/test.rs @@ -1,3 +1,4 @@ + use testutils::{set_ledger_time, setup_test_env}; #[cfg(test)] mod testsuit { proptest! { @@ -54,29 +55,11 @@ mod testsuit { use soroban_sdk::Env; use proptest::prelude::*; - fn set_time(env: &Env, timestamp: u64) { - let proto = env.ledger().protocol_version(); - - env.ledger().set(LedgerInfo { - protocol_version: proto, - sequence_number: 1, - timestamp, - network_id: [0; 32], - base_reserve: 10, - min_temp_entry_ttl: 1, - min_persistent_entry_ttl: 1, - max_entry_ttl: 100000, - }); - } + // Removed local set_time in favor of testutils::set_ledger_time #[test] - fn test_create_bill() { - let env = Env::default(); - let contract_id = env.register_contract(None, BillPayments); - let client = BillPaymentsClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); + fn test_create_bill_succeeds() { + setup_test_env!(env, BillPayments, client, owner); let bill_id = client.create_bill( &owner, @@ -101,13 +84,8 @@ mod testsuit { } #[test] - fn test_create_bill_invalid_amount() { - let env = Env::default(); - let contract_id = env.register_contract(None, BillPayments); - let client = BillPaymentsClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); + fn test_create_bill_invalid_amount_fails() { + setup_test_env!(env, BillPayments, client, owner); let result = client.try_create_bill( &owner, &String::from_str(&env, "Invalid"), @@ -367,9 +345,9 @@ mod testsuit { } #[test] - fn test_get_overdue_bills() { + fn test_get_overdue_bills_succeeds() { let env = Env::default(); - set_time(&env, 2_000_000); + set_ledger_time(&env, 1, 2_000_000); let contract_id = env.register_contract(None, BillPayments); let client = BillPaymentsClient::new(&env, &contract_id); @@ -729,9 +707,9 @@ mod testsuit { } #[test] - fn test_pay_overdue_bill() { + fn test_pay_overdue_bill_succeeds() { let env = Env::default(); - set_time(&env, 2_000_000); // Set time past due date + set_ledger_time(&env, 1, 2_000_000); // Set time past due date let contract_id = env.register_contract(None, BillPayments); let client = BillPaymentsClient::new(&env, &contract_id); let owner = ::generate(&env); diff --git a/data_migration/src/lib.rs b/data_migration/src/lib.rs index 5ec186d..6d41225 100644 --- a/data_migration/src/lib.rs +++ b/data_migration/src/lib.rs @@ -328,7 +328,7 @@ mod tests { use super::*; #[test] - fn snapshot_checksum_roundtrip() { + fn test_snapshot_checksum_roundtrip_succeeds() { let payload = SnapshotPayload::RemittanceSplit(RemittanceSplitExport { owner: "GABC".into(), spending_percent: 50, @@ -343,7 +343,7 @@ mod tests { } #[test] - fn export_import_json() { + fn test_export_import_json_succeeds() { let payload = SnapshotPayload::RemittanceSplit(RemittanceSplitExport { owner: "GXYZ".into(), spending_percent: 40, @@ -359,7 +359,7 @@ mod tests { } #[test] - fn export_import_binary() { + fn test_export_import_binary_succeeds() { let payload = SnapshotPayload::RemittanceSplit(RemittanceSplitExport { owner: "GBIN".into(), spending_percent: 25, @@ -374,7 +374,7 @@ mod tests { } #[test] - fn checksum_mismatch_fails_import() { + fn test_checksum_mismatch_import_fails() { let payload = SnapshotPayload::RemittanceSplit(RemittanceSplitExport { owner: "GX".into(), spending_percent: 100, @@ -389,7 +389,7 @@ mod tests { } #[test] - fn version_compatibility() { + fn test_check_version_compatibility_succeeds() { assert!(check_version_compatibility(1).is_ok()); assert!(check_version_compatibility(SCHEMA_VERSION).is_ok()); assert!(check_version_compatibility(0).is_err()); @@ -397,7 +397,7 @@ mod tests { } #[test] - fn csv_export_import_goals() { + fn test_csv_export_import_goals_succeeds() { let export = SavingsGoalsExport { next_id: 2, goals: vec![SavingsGoalExport { @@ -418,7 +418,7 @@ mod tests { } #[test] - fn migration_event_serialization() { + fn test_migration_event_serialization_succeeds() { let event = MigrationEvent::V1(MigrationEventV1 { contract_id: "CABCD".into(), migration_type: "export".into(), diff --git a/family_wallet/Cargo.toml b/family_wallet/Cargo.toml index 1c63f74..c7c6014 100644 --- a/family_wallet/Cargo.toml +++ b/family_wallet/Cargo.toml @@ -12,4 +12,5 @@ remitwise-common = { path = "../remitwise-common" } [dev-dependencies] soroban-sdk = { version = "21.0.0", features = ["testutils"] } +testutils = { path = "../testutils" } diff --git a/family_wallet/src/test.rs b/family_wallet/src/test.rs index a3cc6a1..59154a5 100644 --- a/family_wallet/src/test.rs +++ b/family_wallet/src/test.rs @@ -5,15 +5,12 @@ use soroban_sdk::{ token::{StellarAssetClient, TokenClient}, vec, Env, }; +use testutils::{set_ledger_time, setup_test_env}; #[test] -fn test_init_family_wallet() { - let env = Env::default(); - env.mock_all_auths(); - let contract_id = env.register_contract(None, FamilyWallet); - let client = FamilyWalletClient::new(&env, &contract_id); +fn test_initialize_wallet_succeeds() { + setup_test_env!(env, FamilyWallet, client, owner); - let owner = Address::generate(&env); let member1 = Address::generate(&env); let member2 = Address::generate(&env); let initial_members = vec![&env, member1.clone(), member2.clone()]; @@ -807,16 +804,7 @@ fn test_instance_ttl_extended_on_init() { let env = Env::default(); env.mock_all_auths(); - env.ledger().set(LedgerInfo { - protocol_version: 20, - sequence_number: 100, - timestamp: 1000, - network_id: [0; 32], - base_reserve: 10, - min_temp_entry_ttl: 100, - min_persistent_entry_ttl: 100, - max_entry_ttl: 700_000, - }); + set_ledger_time(&env, 100, 1000); let contract_id = env.register_contract(None, FamilyWallet); let client = FamilyWalletClient::new(&env, &contract_id); @@ -846,16 +834,7 @@ fn test_instance_ttl_refreshed_on_add_member() { let env = Env::default(); env.mock_all_auths(); - env.ledger().set(LedgerInfo { - protocol_version: 20, - sequence_number: 100, - timestamp: 1000, - network_id: [0; 32], - base_reserve: 10, - min_temp_entry_ttl: 100, - min_persistent_entry_ttl: 100, - max_entry_ttl: 700_000, - }); + set_ledger_time(&env, 100, 1000); let contract_id = env.register_contract(None, FamilyWallet); let client = FamilyWalletClient::new(&env, &contract_id); @@ -868,16 +847,7 @@ fn test_instance_ttl_refreshed_on_add_member() { // Advance ledger so TTL drops below threshold (17,280) // After init at seq 100: live_until = 518,500 // At seq 510,000: TTL = 8,500 < 17,280 ✓ - env.ledger().set(LedgerInfo { - protocol_version: 20, - sequence_number: 510_000, - timestamp: 500_000, - network_id: [0; 32], - base_reserve: 10, - min_temp_entry_ttl: 100, - min_persistent_entry_ttl: 100, - max_entry_ttl: 700_000, - }); + set_ledger_time(&env, 510_000, 500_000); // add_family_member calls extend_instance_ttl → re-extends TTL to 518,400 client.add_family_member(&owner, &member2, &FamilyRole::Member); @@ -901,16 +871,7 @@ fn test_data_persists_across_repeated_operations() { let env = Env::default(); env.mock_all_auths(); - env.ledger().set(LedgerInfo { - protocol_version: 20, - sequence_number: 100, - timestamp: 1000, - network_id: [0; 32], - base_reserve: 10, - min_temp_entry_ttl: 100, - min_persistent_entry_ttl: 100, - max_entry_ttl: 700_000, - }); + set_ledger_time(&env, 100, 1000); let contract_id = env.register_contract(None, FamilyWallet); let client = FamilyWalletClient::new(&env, &contract_id); diff --git a/insurance/Cargo.toml b/insurance/Cargo.toml index 1a5ed2b..412a27b 100644 --- a/insurance/Cargo.toml +++ b/insurance/Cargo.toml @@ -13,5 +13,6 @@ remitwise-common = { path = "../remitwise-common" } [dev-dependencies] proptest = "1.10.0" soroban-sdk = { version = "21.0.0", features = ["testutils"] } +testutils = { path = "../testutils" } diff --git a/insurance/src/test.rs b/insurance/src/test.rs index 0fecd21..076f51d 100644 --- a/insurance/src/test.rs +++ b/insurance/src/test.rs @@ -8,29 +8,13 @@ use soroban_sdk::{ }; use proptest::prelude::*; -fn set_time(env: &Env, timestamp: u64) { - let proto = env.ledger().protocol_version(); - - env.ledger().set(LedgerInfo { - protocol_version: proto, - sequence_number: 1, - timestamp, - network_id: [0; 32], - base_reserve: 10, - min_temp_entry_ttl: 1, - min_persistent_entry_ttl: 1, - max_entry_ttl: 100000, - }); -} +use testutils::{set_ledger_time, setup_test_env}; -#[test] -fn test_create_policy() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = Address::generate(&env); +// Removed local set_time in favor of testutils::set_ledger_time - env.mock_all_auths(); +#[test] +fn test_create_policy_succeeds() { + setup_test_env!(env, Insurance, client, owner); let name = String::from_str(&env, "Health Policy"); let coverage_type = CoverageType::Health; @@ -120,9 +104,7 @@ fn test_pay_premium() { let initial_due = initial_policy.next_payment_date; // Advance ledger time to simulate paying slightly later - let mut ledger_info = env.ledger().get(); - ledger_info.timestamp += 1000; - env.ledger().set(ledger_info); + set_ledger_time(&env, 1, env.ledger().timestamp() + 1000); client.pay_premium(&owner, &policy_id); @@ -537,9 +519,7 @@ fn test_multiple_premium_payments() { client.pay_premium(&owner, &policy_id); // Simulate time passing (still before next due) - let mut ledger = env.ledger().get(); - ledger.timestamp += 5000; - env.ledger().set(ledger); + set_ledger_time(&env, 1, env.ledger().timestamp() + 5000); // Second payment client.pay_premium(&owner, &policy_id); @@ -557,14 +537,9 @@ fn test_multiple_premium_payments() { } #[test] -fn test_create_premium_schedule() { - let env = Env::default(); - let contract_id = env.register_contract(None, Insurance); - let client = InsuranceClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); +fn test_create_premium_schedule_succeeds() { + setup_test_env!(env, Insurance, client, owner); + set_ledger_time(&env, 1000); let policy_id = client.create_policy( &owner, @@ -593,7 +568,7 @@ fn test_modify_premium_schedule() { let owner = ::generate(&env); env.mock_all_auths(); - set_time(&env, 1000); + set_ledger_time(&env, 1, 1000); let policy_id = client.create_policy( &owner, @@ -619,7 +594,7 @@ fn test_cancel_premium_schedule() { let owner = ::generate(&env); env.mock_all_auths(); - set_time(&env, 1000); + set_ledger_time(&env, 1, 1000); let policy_id = client.create_policy( &owner, @@ -644,7 +619,7 @@ fn test_execute_due_premium_schedules() { let owner = ::generate(&env); env.mock_all_auths(); - set_time(&env, 1000); + set_ledger_time(&env, 1, 1000); let policy_id = client.create_policy( &owner, @@ -656,7 +631,7 @@ fn test_execute_due_premium_schedules() { let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &0); - set_time(&env, 3500); + set_ledger_time(&env, 1, 3500); let executed = client.execute_due_premium_schedules(); assert_eq!(executed.len(), 1); @@ -674,7 +649,7 @@ fn test_execute_recurring_premium_schedule() { let owner = ::generate(&env); env.mock_all_auths(); - set_time(&env, 1000); + set_ledger_time(&env, 1, 1000); let policy_id = client.create_policy( &owner, @@ -686,7 +661,7 @@ fn test_execute_recurring_premium_schedule() { let schedule_id = client.create_premium_schedule(&owner, &policy_id, &3000, &2592000); - set_time(&env, 3500); + set_ledger_time(&env, 1, 3500); client.execute_due_premium_schedules(); let schedule = client.get_premium_schedule(&schedule_id).unwrap(); @@ -702,7 +677,7 @@ fn test_execute_missed_premium_schedules() { let owner = ::generate(&env); env.mock_all_auths(); - set_time(&env, 1000); + set_ledger_time(&env, 1, 1000); let policy_id = client.create_policy( &owner, @@ -730,7 +705,7 @@ fn test_get_premium_schedules() { let owner = ::generate(&env); env.mock_all_auths(); - set_time(&env, 1000); + set_ledger_time(&env, 1, 1000); let policy_id1 = client.create_policy( &owner, diff --git a/orchestrator/Cargo.toml b/orchestrator/Cargo.toml index d0a5706..82b0037 100644 --- a/orchestrator/Cargo.toml +++ b/orchestrator/Cargo.toml @@ -11,3 +11,20 @@ soroban-sdk = "21.0.0" [dev-dependencies] soroban-sdk = { version = "21.0.0", features = ["testutils"] } + +testutils = { path = "../testutils" } + +[profile.release] +opt-level = "z" +overflow-checks = true +debug = 0 +strip = "symbols" +debug-assertions = false +panic = "abort" +codegen-units = 1 +lto = true + +[profile.release-with-logs] +inherits = "release" +debug-assertions = true + diff --git a/orchestrator/src/test.rs b/orchestrator/src/test.rs index bfa34e5..7ff66b0 100644 --- a/orchestrator/src/test.rs +++ b/orchestrator/src/test.rs @@ -1,7 +1,6 @@ -// Integration tests for the orchestrator contract - use crate::{Orchestrator, OrchestratorClient, OrchestratorError}; -use soroban_sdk::{contract, contractimpl, testutils::Address as _, Address, Env, Vec}; +use soroban_sdk::{contract, contractimpl, Address, Env, Vec}; +use testutils::{generate_test_address, setup_test_env}; // ============================================================================ // Mock Contract Implementations @@ -113,7 +112,7 @@ mod tests { let insurance_id = env.register_contract(None, MockInsurance); // Create test user address - let user = Address::generate(&env); + let user = generate_test_address(&env); ( env, @@ -128,7 +127,7 @@ mod tests { } #[test] - fn test_successful_savings_deposit() { + fn test_execute_savings_deposit_succeeds() { let ( env, orchestrator_id, @@ -156,7 +155,7 @@ mod tests { } #[test] - fn test_savings_deposit_with_invalid_goal() { + fn test_execute_savings_deposit_invalid_goal_fails() { let ( env, orchestrator_id, @@ -185,7 +184,7 @@ mod tests { } #[test] - fn test_spending_limit_exceeded() { + fn test_execute_savings_deposit_spending_limit_exceeded_fails() { let ( env, orchestrator_id, @@ -219,7 +218,7 @@ mod tests { } #[test] - fn test_successful_bill_payment() { + fn test_execute_bill_payment_succeeds() { let ( env, orchestrator_id, @@ -247,7 +246,7 @@ mod tests { } #[test] - fn test_bill_payment_with_invalid_bill() { + fn test_execute_bill_payment_invalid_bill_fails() { let ( env, orchestrator_id, @@ -276,7 +275,7 @@ mod tests { } #[test] - fn test_successful_insurance_payment() { + fn test_execute_insurance_payment_succeeds() { let ( env, orchestrator_id, @@ -304,7 +303,7 @@ mod tests { } #[test] - fn test_successful_complete_remittance_flow() { + fn test_execute_remittance_flow_succeeds() { let ( env, orchestrator_id, @@ -351,7 +350,7 @@ mod tests { } #[test] - fn test_remittance_flow_bill_payment_failure_causes_rollback() { + fn test_execute_remittance_flow_bill_failure_rolls_back() { let ( env, orchestrator_id, @@ -385,7 +384,7 @@ mod tests { } #[test] - fn test_remittance_flow_savings_failure_causes_rollback() { + fn test_execute_remittance_flow_savings_failure_rolls_back() { let ( env, orchestrator_id, @@ -419,7 +418,7 @@ mod tests { } #[test] - fn test_remittance_flow_exceeds_spending_limit() { + fn test_execute_remittance_flow_spending_limit_exceeded_fails() { let ( env, orchestrator_id, @@ -458,7 +457,7 @@ mod tests { } #[test] - fn test_remittance_flow_invalid_amount() { + fn test_execute_remittance_flow_invalid_amount_fails() { let ( env, orchestrator_id, @@ -495,7 +494,7 @@ mod tests { } #[test] - fn test_get_execution_stats() { + fn test_get_execution_stats_succeeds() { let (env, orchestrator_id, _, _, _, _, _, _) = setup_test_env(); let client = OrchestratorClient::new(&env, &orchestrator_id); @@ -510,7 +509,7 @@ mod tests { } #[test] - fn test_get_audit_log() { + fn test_get_audit_log_succeeds() { let (env, orchestrator_id, _, _, _, _, _, _) = setup_test_env(); let client = OrchestratorClient::new(&env, &orchestrator_id); diff --git a/remittance_split/Cargo.toml b/remittance_split/Cargo.toml index 0cd58c3..ee6cf57 100644 --- a/remittance_split/Cargo.toml +++ b/remittance_split/Cargo.toml @@ -11,5 +11,6 @@ soroban-sdk = "21.0.0" [dev-dependencies] soroban-sdk = { version = "21.0.0", features = ["testutils"] } +testutils = { path = "../testutils" } diff --git a/remittance_split/src/test.rs b/remittance_split/src/test.rs index 88716e0..310b97f 100644 --- a/remittance_split/src/test.rs +++ b/remittance_split/src/test.rs @@ -6,29 +6,13 @@ use soroban_sdk::{ Address, Env, IntoVal, Symbol, TryFromVal, Val, Vec, }; -fn set_time(env: &Env, timestamp: u64) { - let proto = env.ledger().protocol_version(); - - env.ledger().set(LedgerInfo { - protocol_version: proto, - sequence_number: 1, - timestamp, - network_id: [0; 32], - base_reserve: 10, - min_temp_entry_ttl: 1, - min_persistent_entry_ttl: 1, - max_entry_ttl: 100000, - }); -} +use testutils::{set_ledger_time, setup_test_env}; -#[test] -fn test_initialize_split() { - let env = Env::default(); - let contract_id = env.register_contract(None, RemittanceSplit); - let client = RemittanceSplitClient::new(&env, &contract_id); - let owner = Address::generate(&env); +// Removed local set_time in favor of testutils::set_ledger_time - env.mock_all_auths(); +#[test] +fn test_initialize_split_succeeds() { + setup_test_env!(env, RemittanceSplit, client, owner); let success = client.initialize_split( &owner, &0, // nonce @@ -215,14 +199,9 @@ fn test_calculate_complex_rounding() { } #[test] -fn test_create_remittance_schedule() { - let env = Env::default(); - let contract_id = env.register_contract(None, RemittanceSplit); - let client = RemittanceSplitClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); +fn test_create_remittance_schedule_succeeds() { + setup_test_env!(env, RemittanceSplit, client, owner); + set_ledger_time(&env, 1000); client.initialize_split(&owner, &0, &50, &30, &15, &5); diff --git a/reporting/Cargo.toml b/reporting/Cargo.toml index bd968c8..8fe34d3 100644 --- a/reporting/Cargo.toml +++ b/reporting/Cargo.toml @@ -12,3 +12,4 @@ remitwise-common = { path = "../remitwise-common" } [dev-dependencies] soroban-sdk = { version = "21.0.0", features = ["testutils"] } +testutils = { path = "../testutils" } diff --git a/reporting/src/tests.rs b/reporting/src/tests.rs index e61bde8..d6c0101 100644 --- a/reporting/src/tests.rs +++ b/reporting/src/tests.rs @@ -1,9 +1,4 @@ -use super::*; -use soroban_sdk::testutils::storage::Instance as _; -use soroban_sdk::{ - testutils::{Address as _, Ledger, LedgerInfo}, - Address, Env, -}; +use testutils::{set_ledger_time}; // Mock contracts for testing mod remittance_split { @@ -188,25 +183,12 @@ mod insurance { } } -fn create_test_env() -> Env { - let env = Env::default(); - env.mock_all_auths(); - env.ledger().set(LedgerInfo { - timestamp: 1704067200, // Jan 1, 2024 - protocol_version: 20, - sequence_number: 1, - network_id: [0; 32], - base_reserve: 10, - min_temp_entry_ttl: 10, - min_persistent_entry_ttl: 10, - max_entry_ttl: 3110400, - }); - env -} +// create_test_env removed in favor of testutils and Env::default() #[test] -fn test_init_reporting_contract() { - let env = create_test_env(); +fn test_init_reporting_contract_succeeds() { + let env = Env::default(); + env.mock_all_auths(); let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let admin = Address::generate(&env); @@ -219,7 +201,8 @@ fn test_init_reporting_contract() { #[test] fn test_init_twice_fails() { - let env = create_test_env(); + let env = Env::default(); + env.mock_all_auths(); let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let admin = Address::generate(&env); @@ -230,8 +213,9 @@ fn test_init_twice_fails() { } #[test] -fn test_configure_addresses() { - let env = create_test_env(); +fn test_configure_addresses_succeeds() { + let env = Env::default(); + env.mock_all_auths(); let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let admin = Address::generate(&env); @@ -292,7 +276,9 @@ fn test_configure_addresses_unauthorized() { #[test] fn test_get_remittance_summary() { - let env = create_test_env(); + let env = Env::default(); + env.mock_all_auths(); + set_ledger_time(&env, 1, 1704067200); // Standard timestamp for reporting tests let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let admin = Address::generate(&env); @@ -337,7 +323,9 @@ fn test_get_remittance_summary() { #[test] fn test_get_savings_report() { - let env = create_test_env(); + let env = Env::default(); + env.mock_all_auths(); + set_ledger_time(&env, 1, 1704067200); // Standard timestamp for reporting tests let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let admin = Address::generate(&env); @@ -374,7 +362,9 @@ fn test_get_savings_report() { #[test] fn test_get_bill_compliance_report() { - let env = create_test_env(); + let env = Env::default(); + env.mock_all_auths(); + set_ledger_time(&env, 1, 1704067200); // Standard timestamp for reporting tests let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let admin = Address::generate(&env); @@ -410,7 +400,9 @@ fn test_get_bill_compliance_report() { #[test] fn test_get_insurance_report() { - let env = create_test_env(); + let env = Env::default(); + env.mock_all_auths(); + set_ledger_time(&env, 1, 1704067200); // Standard timestamp for reporting tests let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let admin = Address::generate(&env); @@ -447,7 +439,9 @@ fn test_get_insurance_report() { #[test] fn test_calculate_health_score() { - let env = create_test_env(); + let env = Env::default(); + env.mock_all_auths(); + set_ledger_time(&env, 1, 1704067200); // Standard timestamp for reporting tests let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let admin = Address::generate(&env); @@ -484,7 +478,9 @@ fn test_calculate_health_score() { #[test] fn test_get_financial_health_report() { - let env = create_test_env(); + let env = Env::default(); + env.mock_all_auths(); + set_ledger_time(&env, 1, 1704067200); // Standard timestamp for reporting tests let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let admin = Address::generate(&env); @@ -523,7 +519,9 @@ fn test_get_financial_health_report() { #[test] fn test_get_trend_analysis() { - let env = create_test_env(); + let env = Env::default(); + env.mock_all_auths(); + set_ledger_time(&env, 1, 1704067200); // Standard timestamp for reporting tests let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let user = Address::generate(&env); @@ -541,7 +539,9 @@ fn test_get_trend_analysis() { #[test] fn test_get_trend_analysis_decrease() { - let env = create_test_env(); + let env = Env::default(); + env.mock_all_auths(); + set_ledger_time(&env, 1, 1704067200); // Standard timestamp for reporting tests let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let user = Address::generate(&env); @@ -559,7 +559,9 @@ fn test_get_trend_analysis_decrease() { #[test] fn test_store_and_retrieve_report() { - let env = create_test_env(); + let env = Env::default(); + env.mock_all_auths(); + set_ledger_time(&env, 1, 1704067200); // Standard timestamp for reporting tests let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let admin = Address::generate(&env); @@ -609,7 +611,9 @@ fn test_store_and_retrieve_report() { #[test] fn test_retrieve_nonexistent_report() { - let env = create_test_env(); + let env = Env::default(); + env.mock_all_auths(); + set_ledger_time(&env, 1, 1704067200); // Standard timestamp for reporting tests let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let user = Address::generate(&env); @@ -620,7 +624,9 @@ fn test_retrieve_nonexistent_report() { #[test] fn test_health_score_no_goals() { - let env = create_test_env(); + let env = Env::default(); + env.mock_all_auths(); + set_ledger_time(&env, 1, 1704067200); // Standard timestamp for reporting tests let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let admin = Address::generate(&env); @@ -675,7 +681,9 @@ fn test_health_score_no_goals() { #[test] fn test_archive_old_reports() { - let env = create_test_env(); + let env = Env::default(); + env.mock_all_auths(); + set_ledger_time(&env, 1, 1704067200); // Standard timestamp for reporting tests let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let admin = Address::generate(&env); @@ -726,7 +734,9 @@ fn test_archive_old_reports() { #[test] fn test_archive_empty_when_no_old_reports() { - let env = create_test_env(); + let env = Env::default(); + env.mock_all_auths(); + set_ledger_time(&env, 1, 1704067200); // Standard timestamp for reporting tests let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let admin = Address::generate(&env); @@ -740,7 +750,9 @@ fn test_archive_empty_when_no_old_reports() { #[test] fn test_cleanup_old_reports() { - let env = create_test_env(); + let env = Env::default(); + env.mock_all_auths(); + set_ledger_time(&env, 1, 1704067200); // Standard timestamp for reporting tests let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let admin = Address::generate(&env); @@ -781,7 +793,9 @@ fn test_cleanup_old_reports() { #[test] fn test_storage_stats() { - let env = create_test_env(); + let env = Env::default(); + env.mock_all_auths(); + set_ledger_time(&env, 1, 1704067200); // Standard timestamp for reporting tests let contract_id = env.register_contract(None, ReportingContract); let client = ReportingContractClient::new(&env, &contract_id); let admin = Address::generate(&env); diff --git a/savings_goals/Cargo.toml b/savings_goals/Cargo.toml index 1e1dff0..0ffb4e5 100644 --- a/savings_goals/Cargo.toml +++ b/savings_goals/Cargo.toml @@ -11,5 +11,6 @@ soroban-sdk = "21.0.0" [dev-dependencies] soroban-sdk = { version = "21.0.0", features = ["testutils"] } +testutils = { path = "../testutils" } diff --git a/savings_goals/src/test.rs b/savings_goals/src/test.rs index 72b35fe..9cb277a 100644 --- a/savings_goals/src/test.rs +++ b/savings_goals/src/test.rs @@ -7,36 +7,18 @@ use soroban_sdk::{ Address, Env, String, Symbol, TryFromVal, }; -fn set_time(env: &Env, timestamp: u64) { - let proto = env.ledger().protocol_version(); +use testutils::{set_ledger_time, setup_test_env}; - env.ledger().set(LedgerInfo { - protocol_version: proto, - sequence_number: 1, - timestamp, - network_id: [0; 32], - base_reserve: 10, - min_temp_entry_ttl: 1, - min_persistent_entry_ttl: 1, - max_entry_ttl: 100000, - }); -} +// Removed local set_time in favor of testutils::set_ledger_time #[test] -fn test_create_goal_unique_ids() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let user = Address::generate(&env); - +fn test_create_goal_unique_ids_succeeds() { + setup_test_env!(env, SavingsGoalContract, client, user); client.init(); let name1 = String::from_str(&env, "Goal 1"); let name2 = String::from_str(&env, "Goal 2"); - // Tell the environment to auto-approve the 'user' signature - env.mock_all_auths(); - let id1 = client.create_goal(&user, &name1, &1000, &1735689600); let id2 = client.create_goal(&user, &name2, &2000, &1735689600); @@ -494,14 +476,10 @@ fn test_exact_goal_completion() { } #[test] -fn test_set_time_lock() { - let env = Env::default(); - let contract_id = env.register_contract(None, SavingsGoalContract); - let client = SavingsGoalContractClient::new(&env, &contract_id); - let owner = ::generate(&env); - - env.mock_all_auths(); - set_time(&env, 1000); +fn test_set_time_lock_succeeds() { + setup_test_env!(env, SavingsGoalContract, client, owner); + client.init(); + set_ledger_time(&env, 1, 1000); let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); @@ -519,7 +497,7 @@ fn test_withdraw_time_locked_goal_before_unlock() { let owner = ::generate(&env); env.mock_all_auths(); - set_time(&env, 1000); + set_ledger_time(&env, 1, 1000); let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); @@ -539,7 +517,7 @@ fn test_withdraw_time_locked_goal_after_unlock() { let owner = ::generate(&env); env.mock_all_auths(); - set_time(&env, 1000); + set_ledger_time(&env, 1, 1000); let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); @@ -547,7 +525,7 @@ fn test_withdraw_time_locked_goal_after_unlock() { client.unlock_goal(&owner, &goal_id); client.set_time_lock(&owner, &goal_id, &3000); - set_time(&env, 3500); + set_ledger_time(&env, 1, 3500); let new_amount = client.withdraw_from_goal(&owner, &goal_id, &1000); assert_eq!(new_amount, 4000); } @@ -560,7 +538,7 @@ fn test_create_savings_schedule() { let owner = ::generate(&env); env.mock_all_auths(); - set_time(&env, 1000); + set_ledger_time(&env, 1, 1000); let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); @@ -583,7 +561,7 @@ fn test_modify_savings_schedule() { let owner = ::generate(&env); env.mock_all_auths(); - set_time(&env, 1000); + set_ledger_time(&env, 1, 1000); let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); @@ -604,7 +582,7 @@ fn test_cancel_savings_schedule() { let owner = ::generate(&env); env.mock_all_auths(); - set_time(&env, 1000); + set_ledger_time(&env, 1, 1000); let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); @@ -623,13 +601,13 @@ fn test_execute_due_savings_schedules() { let owner = ::generate(&env); env.mock_all_auths(); - set_time(&env, 1000); + set_ledger_time(&env, 1, 1000); let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &0); - set_time(&env, 3500); + set_ledger_time(&env, 1, 3500); let executed = client.execute_due_savings_schedules(); assert_eq!(executed.len(), 1); @@ -647,13 +625,13 @@ fn test_execute_recurring_savings_schedule() { let owner = ::generate(&env); env.mock_all_auths(); - set_time(&env, 1000); + set_ledger_time(&env, 1, 1000); let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); - set_time(&env, 3500); + set_ledger_time(&env, 1, 3500); client.execute_due_savings_schedules(); let schedule = client.get_savings_schedule(&schedule_id).unwrap(); @@ -672,13 +650,13 @@ fn test_execute_missed_savings_schedules() { let owner = ::generate(&env); env.mock_all_auths(); - set_time(&env, 1000); + set_ledger_time(&env, 1, 1000); let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &10000, &5000); let schedule_id = client.create_savings_schedule(&owner, &goal_id, &500, &3000, &86400); - set_time(&env, 3000 + 86400 * 3 + 100); + set_ledger_time(&env, 1, 3000 + 86400 * 3 + 100); client.execute_due_savings_schedules(); let schedule = client.get_savings_schedule(&schedule_id).unwrap(); @@ -694,13 +672,13 @@ fn test_savings_schedule_goal_completion() { let owner = ::generate(&env); env.mock_all_auths(); - set_time(&env, 1000); + set_ledger_time(&env, 1, 1000); let goal_id = client.create_goal(&owner, &String::from_str(&env, "Education"), &1000, &5000); client.create_savings_schedule(&owner, &goal_id, &1000, &3000, &0); - set_time(&env, 3500); + set_ledger_time(&env, 1, 3500); client.execute_due_savings_schedules(); let goal = client.get_goal(&goal_id).unwrap(); diff --git a/scenarios/Cargo.toml b/scenarios/Cargo.toml index ca01c7e..e7a4f5d 100644 --- a/scenarios/Cargo.toml +++ b/scenarios/Cargo.toml @@ -6,6 +6,7 @@ publish = false [dependencies] soroban-sdk = { version = "21.0.0", features = ["testutils"] } +testutils = { path = "../testutils" } remittance_split = { path = "../remittance_split" } savings_goals = { path = "../savings_goals" } bill_payments = { path = "../bill_payments" } diff --git a/scenarios/src/lib.rs b/scenarios/src/lib.rs index 336ce92..d7f43a3 100644 --- a/scenarios/src/lib.rs +++ b/scenarios/src/lib.rs @@ -1,20 +1,13 @@ pub mod tests { + use soroban_sdk::Env; + use testutils::set_ledger_time; use soroban_sdk::testutils::{Ledger, LedgerInfo}; use soroban_sdk::Env; pub fn setup_env() -> Env { let env = Env::default(); env.mock_all_auths(); - env.ledger().set(LedgerInfo { - timestamp: 1704067200, // Jan 1, 2024 - protocol_version: 20, - sequence_number: 1, - network_id: [0; 32], - base_reserve: 10, - min_temp_entry_ttl: 10, - min_persistent_entry_ttl: 10, - max_entry_ttl: 3110400, - }); + set_ledger_time(&env, 1, 1704067200); // Jan 1, 2024 env } } diff --git a/testutils/Cargo.toml b/testutils/Cargo.toml new file mode 100644 index 0000000..4851acc --- /dev/null +++ b/testutils/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "testutils" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +soroban-sdk = { version = "21.0.0", features = ["testutils"] } diff --git a/testutils/src/lib.rs b/testutils/src/lib.rs new file mode 100644 index 0000000..b41c7b5 --- /dev/null +++ b/testutils/src/lib.rs @@ -0,0 +1,35 @@ +#![no_std] +use soroban_sdk::{ + testutils::{Address as AddressTrait, Ledger, LedgerInfo}, + Address, Env, +}; + +pub fn set_ledger_time(env: &Env, sequence_number: u32, timestamp: u64) { + let proto = env.ledger().protocol_version(); + + env.ledger().set(LedgerInfo { + protocol_version: proto, + sequence_number, + timestamp, + network_id: [0; 32], + base_reserve: 10, + min_temp_entry_ttl: 1, + min_persistent_entry_ttl: 1, + max_entry_ttl: 100000, + }); +} + +pub fn generate_test_address(env: &Env) -> Address { + Address::generate(env) +} + +#[macro_export] +macro_rules! setup_test_env { + ($env:ident, $contract:ident, $client:ident, $owner:ident) => { + let $env = Env::default(); + $env.mock_all_auths(); + let contract_id = $env.register_contract(None, $contract); + let $client = $contract::Client::new(&$env, &contract_id); + let $owner = $crate::generate_test_address(&$env); + }; +}