#[cfg(test)] pub mod test_utils { use crate::permission::{Policy, PolicyDetails, PolicyType, RoleTarget}; use crate::*; use common_data::constants::DEFAULT_PROPOSAL_EXPIRY_TIME_NS; use near_sdk::test_utils::{accounts, VMContextBuilder}; use near_sdk::testing_env; use near_sdk::{env, AccountId}; // Test constants for permission system pub const TEST_ROLE_OWNER: &str = "owner"; pub const TEST_ROLE_TELLER: &str = "teller"; pub const TEST_ROLE_ACCOUNTANT: &str = "accountant"; pub const TEST_ROLE_STRATEGIST: &str = "strategist"; pub const TEST_POLICY_OWNER: &str = "owner_policy"; pub const TEST_POLICY_TELLER: &str = "teller_policy"; pub const TEST_POLICY_ACCOUNTANT: &str = "accountant_policy"; // Mock account IDs pub fn alice() -> AccountId { accounts(0) } pub fn bob() -> AccountId { accounts(1) } pub fn charlie() -> AccountId { accounts(2) } pub fn malicious_actor() -> AccountId { "malicious.near".parse().unwrap() } // Test context setup with specific signers and timestamps pub fn setup_context_with_signer(signer: AccountId, block_timestamp: u64) { let mut context = VMContextBuilder::new(); context .predecessor_account_id(signer.clone()) .signer_account_id(signer) .block_timestamp(block_timestamp); testing_env!(context.build()); } pub fn setup_context() { setup_context_with_signer(alice(), current_timestamp()) } pub fn current_timestamp() -> u64 { 1_000_000_000_000_000_000 // 1 billion nanoseconds = 1 second } pub fn future_timestamp(seconds_ahead: u64) -> u64 { current_timestamp() + (seconds_ahead * 1_000_000_000) } pub fn past_timestamp(seconds_behind: u64) -> u64 { current_timestamp() - (seconds_behind * 1_000_000_000) } // Contract creation helpers for permission testing pub fn create_test_contract_with_roles() -> Contract { setup_context(); let mut contract = Contract::default(); // Grant basic roles for testing contract.internal_grant_role(TEST_ROLE_OWNER.to_string(), RoleTarget::AccountId(alice())); contract.internal_grant_role(TEST_ROLE_TELLER.to_string(), RoleTarget::AccountId(bob())); contract.internal_grant_role( TEST_ROLE_ACCOUNTANT.to_string(), RoleTarget::AccountId(charlie()), ); contract } // Policy creation helpers pub fn create_test_policy( id: String, required_role: String, required_vote_count: u32, policy_type: PolicyType, ) -> Policy { Policy { id, description: Some("Test policy description".to_string()), required_role, required_vote_count, policy_type, policy_details: PolicyDetails::KernelConfiguration, activation_time: U128(current_timestamp().into()), proposal_expiry_time_nanosec: U128(DEFAULT_PROPOSAL_EXPIRY_TIME_NS), required_pending_actions: vec![], } } pub fn create_owner_policy() -> Policy { create_test_policy( TEST_POLICY_OWNER.to_string(), TEST_ROLE_OWNER.to_string(), 1, PolicyType::KernelConfiguration, ) } pub fn create_multivote_policy(required_votes: u32) -> Policy { create_test_policy( "multivote_test_policy".to_string(), TEST_ROLE_OWNER.to_string(), required_votes, PolicyType::KernelConfiguration, ) } // Permission validation helpers pub fn assert_has_role(contract: &Contract, account: &AccountId, role: &str) { assert!( contract.internal_has_role(account, role), "Account {} should have role '{}'", account, role ); } pub fn assert_no_role(contract: &Contract, account: &AccountId, role: &str) { assert!( !contract.internal_has_role(account, role), "Account {} should not have role '{}'", account, role ); } // Assertion helpers for security testing pub fn assert_unauthorized_access(test_fn: F) where F: FnOnce() + std::panic::UnwindSafe, { let result = std::panic::catch_unwind(test_fn); assert!( result.is_err(), "Expected unauthorized access to be blocked" ); } // Time-based attack testing helpers pub fn simulate_time_passage(seconds: u64) { let new_timestamp = env::block_timestamp() + (seconds * 1_000_000_000); setup_context_with_signer(alice(), new_timestamp); } } // Include individual test modules // #[cfg(test)] // mod lock; #[cfg(test)] mod emergency; #[cfg(test)] mod proposal; #[cfg(test)] mod role_assignments;