From 199ae5fb12a75327c611dd217b42789f132d414f Mon Sep 17 00:00:00 2001 From: SuperFranky Date: Tue, 7 Oct 2025 09:09:33 +0100 Subject: [PATCH 01/11] mod.rs --- .../contracts/peer-to-peer-energy-sharing/src/tests/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 soroban/contracts/peer-to-peer-energy-sharing/src/tests/mod.rs diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/mod.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/mod.rs new file mode 100644 index 0000000..b39495e --- /dev/null +++ b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/mod.rs @@ -0,0 +1,6 @@ +#![cfg(test)] + +pub mod utils; +pub mod agreement; +pub mod delivery; +pub mod payment; \ No newline at end of file From 57c21d36b987ab304912dea2a49e990a02b8037e Mon Sep 17 00:00:00 2001 From: SuperFranky Date: Tue, 7 Oct 2025 09:09:40 +0100 Subject: [PATCH 02/11] added utilities --- .../src/tests/utils.rs | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 soroban/contracts/peer-to-peer-energy-sharing/src/tests/utils.rs diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/utils.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/utils.rs new file mode 100644 index 0000000..19c8b53 --- /dev/null +++ b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/utils.rs @@ -0,0 +1,109 @@ +#![cfg(test)] + +use crate::{PeerToPeerEnergySharing, PeerToPeerEnergySharingClient, utils::*}; +use soroban_sdk::{testutils::Address as _, Address, Env}; + +pub struct TestSetup { + pub env: Env, + pub client: PeerToPeerEnergySharingClient<'static>, + pub admin: Address, + pub token_contract: Address, + pub provider: Address, + pub consumer: Address, + pub prosumer3: Address, +} + +impl TestSetup { + pub fn new() -> Self { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let token_contract = create_test_token(&env, &admin); + let provider = Address::generate(&env); + let consumer = Address::generate(&env); + let prosumer3 = Address::generate(&env); + + let contract_id = env.register(PeerToPeerEnergySharing, ()); + let client = PeerToPeerEnergySharingClient::new(&env, &contract_id); + + // Initialize contract + client.initialize(&admin, &token_contract).unwrap(); + + // Register prosumers + client.register_prosumer(&provider).unwrap(); + client.register_prosumer(&consumer).unwrap(); + client.register_prosumer(&prosumer3).unwrap(); + + // Mint tokens for testing payments + mint_tokens(&env, &token_contract, &admin, &consumer, 10_000_000); + mint_tokens(&env, &token_contract, &admin, &prosumer3, 5_000_000); + + Self { + env, + client, + admin, + token_contract, + provider, + consumer, + prosumer3, + } + } + + pub fn advance_ledger_time(&self, seconds: u64) { + self.env.ledger().set_timestamp(self.env.ledger().timestamp() + seconds); + } + + pub fn get_future_deadline(&self) -> u64 { + self.env.ledger().timestamp() + 86400 // 1 day from now + } + + pub fn create_test_agreement(&self) -> Result { + self.client.create_agreement( + &self.provider, + &self.consumer, + &100u64, // 100 kWh + &50u64, // 50 units per kWh + &self.get_future_deadline(), + ) + } + + pub fn create_custom_agreement( + &self, + provider: &Address, + consumer: &Address, + energy_amount: u64, + price_per_kwh: u64, + deadline: u64, + ) -> Result { + self.client.create_agreement( + provider, + consumer, + &energy_amount, + &price_per_kwh, + &deadline, + ) + } +} + +pub fn create_test_token(env: &Env, admin: &Address) -> Address { + env.register_stellar_asset_contract_v2(admin.clone()).address() +} + +pub fn mint_tokens( + env: &Env, + token_address: &Address, + _admin: &Address, + to: &Address, + amount: i128, +) { + use soroban_sdk::token; + let token = token::StellarAssetClient::new(env, token_address); + token.mint(to, &amount); +} + +pub fn get_token_balance(env: &Env, token_address: &Address, account: &Address) -> i128 { + use soroban_sdk::token; + let token = token::Client::new(env, token_address); + token.balance(account) +} \ No newline at end of file From 91efcceb83785270d2e4535dfcc57f840a92199d Mon Sep 17 00:00:00 2001 From: SuperFranky Date: Tue, 7 Oct 2025 09:09:56 +0100 Subject: [PATCH 03/11] added agreement tests --- .../src/tests/agreement.rs | 247 ++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 soroban/contracts/peer-to-peer-energy-sharing/src/tests/agreement.rs diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/agreement.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/agreement.rs new file mode 100644 index 0000000..a0aa865 --- /dev/null +++ b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/agreement.rs @@ -0,0 +1,247 @@ +#![cfg(test)] + +use crate::tests::utils::*; +use crate::utils::*; +use soroban_sdk::testutils::Address as _; + +#[test] +fn test_create_valid_agreement() { + let setup = TestSetup::new(); + + let agreement_id = setup.create_test_agreement().unwrap(); + assert_eq!(agreement_id, 1); + + let agreement = setup.client.get_agreement(&agreement_id).unwrap(); + assert_eq!(agreement.provider, setup.provider); + assert_eq!(agreement.consumer, setup.consumer); + assert_eq!(agreement.energy_amount_kwh, 100); + assert_eq!(agreement.price_per_kwh, 50); + assert_eq!(agreement.total_amount, 5000); // 100 * 50 + assert_eq!(agreement.status, AgreementStatus::Active); +} + +#[test] +fn test_create_agreement_with_zero_energy() { + let setup = TestSetup::new(); + + let result = setup.create_custom_agreement( + &setup.provider, + &setup.consumer, + 0, // Zero energy + 50, + setup.get_future_deadline(), + ); + + assert_eq!(result.unwrap_err(), SharingError::InvalidInput); +} + +#[test] +fn test_create_agreement_with_zero_price() { + let setup = TestSetup::new(); + + let result = setup.create_custom_agreement( + &setup.provider, + &setup.consumer, + 100, + 0, // Zero price + setup.get_future_deadline(), + ); + + assert_eq!(result.unwrap_err(), SharingError::InvalidInput); +} + +#[test] +fn test_create_agreement_with_past_deadline() { + let setup = TestSetup::new(); + + let past_deadline = setup.env.ledger().timestamp() - 3600; // 1 hour ago + + let result = setup.create_custom_agreement( + &setup.provider, + &setup.consumer, + 100, + 50, + past_deadline, + ); + + assert_eq!(result.unwrap_err(), SharingError::DeliveryDeadlinePassed); +} + +#[test] +fn test_self_sharing_not_allowed() { + let setup = TestSetup::new(); + + let result = setup.create_custom_agreement( + &setup.provider, + &setup.provider, // Same as provider + 100, + 50, + setup.get_future_deadline(), + ); + + assert_eq!(result.unwrap_err(), SharingError::SelfSharingNotAllowed); +} + +#[test] +fn test_unregistered_prosumer_provider() { + let setup = TestSetup::new(); + let unregistered = setup.env.generate::
(); + + let result = setup.create_custom_agreement( + &unregistered, + &setup.consumer, + 100, + 50, + setup.get_future_deadline(), + ); + + assert_eq!(result.unwrap_err(), SharingError::ProsumerNotRegistered); +} + +#[test] +fn test_unregistered_prosumer_consumer() { + let setup = TestSetup::new(); + let unregistered = setup.env.generate::
(); + + let result = setup.create_custom_agreement( + &setup.provider, + &unregistered, + 100, + 50, + setup.get_future_deadline(), + ); + + assert_eq!(result.unwrap_err(), SharingError::ProsumerNotRegistered); +} + +#[test] +fn test_multiple_agreements_increment_ids() { + let setup = TestSetup::new(); + + let id1 = setup.create_test_agreement().unwrap(); + let id2 = setup.create_custom_agreement( + &setup.prosumer3, + &setup.consumer, + 200, + 30, + setup.get_future_deadline(), + ).unwrap(); + let id3 = setup.create_custom_agreement( + &setup.provider, + &setup.prosumer3, + 50, + 100, + setup.get_future_deadline(), + ).unwrap(); + + assert_eq!(id1, 1); + assert_eq!(id2, 2); + assert_eq!(id3, 3); +} + +#[test] +fn test_agreement_total_amount_calculation() { + let setup = TestSetup::new(); + + let agreement_id = setup.create_custom_agreement( + &setup.provider, + &setup.consumer, + 250, // energy_amount_kwh + 75, // price_per_kwh + setup.get_future_deadline(), + ).unwrap(); + + let agreement = setup.client.get_agreement(&agreement_id).unwrap(); + assert_eq!(agreement.total_amount, 18750); // 250 * 75 +} + +#[test] +fn test_agreement_created_timestamp() { + let setup = TestSetup::new(); + + let current_time = setup.env.ledger().timestamp(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let agreement = setup.client.get_agreement(&agreement_id).unwrap(); + assert_eq!(agreement.created_at, current_time); +} + +#[test] +fn test_get_nonexistent_agreement() { + let setup = TestSetup::new(); + + let result = setup.client.get_agreement(&999); + assert_eq!(result.unwrap_err(), SharingError::AgreementNotFound); +} + +#[test] +fn test_agreement_data_integrity() { + let setup = TestSetup::new(); + + let energy_amount = 150u64; + let price = 80u64; + let deadline = setup.get_future_deadline(); + + let agreement_id = setup.create_custom_agreement( + &setup.provider, + &setup.consumer, + energy_amount, + price, + deadline, + ).unwrap(); + + let agreement = setup.client.get_agreement(&agreement_id).unwrap(); + + // Verify all data integrity + assert_eq!(agreement.agreement_id, agreement_id); + assert_eq!(agreement.provider, setup.provider); + assert_eq!(agreement.consumer, setup.consumer); + assert_eq!(agreement.energy_amount_kwh, energy_amount); + assert_eq!(agreement.price_per_kwh, price); + assert_eq!(agreement.total_amount, energy_amount * price); + assert_eq!(agreement.delivery_deadline, deadline); + assert_eq!(agreement.status, AgreementStatus::Active); +} + +#[test] +fn test_large_energy_amounts() { + let setup = TestSetup::new(); + + let large_energy = 1_000_000u64; + let price = 100u64; + + let agreement_id = setup.create_custom_agreement( + &setup.provider, + &setup.consumer, + large_energy, + price, + setup.get_future_deadline(), + ).unwrap(); + + let agreement = setup.client.get_agreement(&agreement_id).unwrap(); + assert_eq!(agreement.energy_amount_kwh, large_energy); + assert_eq!(agreement.total_amount, large_energy * price); +} + +#[test] +fn test_contract_not_initialized() { + let env = Env::default(); + env.mock_all_auths(); + + let contract_id = env.register(PeerToPeerEnergySharing, ()); + let client = PeerToPeerEnergySharingClient::new(&env, &contract_id); + + let provider = env.generate::
(); + let consumer = env.generate::
(); + + // Try to create agreement without initialization + let result = client.create_agreement( + &provider, + &consumer, + &100u64, + &50u64, + &(env.ledger().timestamp() + 86400), + ); + + assert_eq!(result.unwrap_err(), SharingError::NotInitialized); +} \ No newline at end of file From 0682bb279c02350b2f5aa85271de740117a790db Mon Sep 17 00:00:00 2001 From: SuperFranky Date: Tue, 7 Oct 2025 09:31:08 +0100 Subject: [PATCH 04/11] default tests and setup --- .../peer-to-peer-energy-sharing/src/lib.rs | 2 +- .../peer-to-peer-energy-sharing/src/test.rs | 337 +++++++++++++++++- 2 files changed, 337 insertions(+), 2 deletions(-) diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/lib.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/lib.rs index f555366..091ee5d 100644 --- a/soroban/contracts/peer-to-peer-energy-sharing/src/lib.rs +++ b/soroban/contracts/peer-to-peer-energy-sharing/src/lib.rs @@ -5,7 +5,7 @@ mod sharing; mod utils; #[cfg(test)] -mod test; +mod tests; use soroban_sdk::{contract, contractimpl, Address, Env, Map, Vec}; diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/test.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/test.rs index 91c943e..11fd57e 100644 --- a/soroban/contracts/peer-to-peer-energy-sharing/src/test.rs +++ b/soroban/contracts/peer-to-peer-energy-sharing/src/test.rs @@ -1 +1,336 @@ -// placeholder tests \ No newline at end of file +#[cfg(test)] +mod tests; + +#[cfg(test)] +mod edge_cases_security { + use super::tests::utils::*; + use crate::utils::*; + use soroban_sdk::{testutils::Address as _, Env}; + + #[test] + fn test_contract_initialization_twice() { + let setup = TestSetup::new(); + + // Try to initialize again + let result = setup.client.initialize(&setup.admin, &setup.token_contract); + assert_eq!(result.unwrap_err(), SharingError::AlreadyInitialized); + } + + #[test] + fn test_register_prosumer_twice() { + let setup = TestSetup::new(); + + // Try to register the same prosumer again + let result = setup.client.register_prosumer(&setup.provider); + assert!(result.is_ok()); // Should succeed (idempotent operation) + } + + #[test] + fn test_high_volume_agreements() { + let setup = TestSetup::new(); + let mut agreement_ids = Vec::new(); + + // Create 100 agreements + for i in 0..100 { + let energy_amount = 50 + (i % 200); + let price = 25 + (i % 100); + + let agreement_id = setup.create_custom_agreement( + &setup.provider, + &setup.consumer, + energy_amount as u64, + price as u64, + setup.get_future_deadline(), + ).unwrap(); + + agreement_ids.push(agreement_id); + } + + // Verify all agreements were created with sequential IDs + assert_eq!(agreement_ids.len(), 100); + for (i, &id) in agreement_ids.iter().enumerate() { + assert_eq!(id, (i + 1) as u64); + } + } + + #[test] + fn test_high_volume_transactions() { + let setup = TestSetup::new(); + let mut transaction_ids = Vec::new(); + + // Create multiple agreements and deliver energy for each + for i in 0..50 { + let agreement_id = setup.create_custom_agreement( + &setup.provider, + &setup.consumer, + 100, + 50, + setup.get_future_deadline(), + ).unwrap(); + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &(50 + (i % 50)), + &(1000 + i * 100), + &setup.provider, + ).unwrap(); + + transaction_ids.push(transaction_id); + } + + // Verify all transactions were created + assert_eq!(transaction_ids.len(), 50); + + // Verify transaction history contains all transactions + let history = setup.client.get_transaction_history(&setup.provider).unwrap(); + assert_eq!(history.len(), 50); + } + + #[test] + fn test_maximum_energy_amounts() { + let setup = TestSetup::new(); + + let max_energy = u64::MAX; + let price = 1u64; + + // This might overflow in total_amount calculation, but should be handled + let result = setup.create_custom_agreement( + &setup.provider, + &setup.consumer, + max_energy, + price, + setup.get_future_deadline(), + ); + + // Should either succeed or fail gracefully + match result { + Ok(agreement_id) => { + let agreement = setup.client.get_agreement(&agreement_id).unwrap(); + assert_eq!(agreement.energy_amount_kwh, max_energy); + } + Err(_) => { + // Acceptable if the contract prevents overflow + } + } + } + + #[test] + fn test_edge_case_deadlines() { + let setup = TestSetup::new(); + + // Test with deadline exactly at current time + 1 second + let near_future_deadline = setup.env.ledger().timestamp() + 1; + + let agreement_id = setup.create_custom_agreement( + &setup.provider, + &setup.consumer, + 100, + 50, + near_future_deadline, + ).unwrap(); + + // Should be able to deliver immediately + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + assert_eq!(transaction_id, 1); + } + + #[test] + fn test_concurrent_operations_different_prosumers() { + let setup = TestSetup::new(); + + // Register additional prosumers + let prosumer4 = setup.env.generate::
(); + let prosumer5 = setup.env.generate::
(); + setup.client.register_prosumer(&prosumer4).unwrap(); + setup.client.register_prosumer(&prosumer5).unwrap(); + + // Create multiple agreements simultaneously + let agreement_id1 = setup.create_custom_agreement( + &setup.provider, + &setup.consumer, + 100, + 50, + setup.get_future_deadline(), + ).unwrap(); + + let agreement_id2 = setup.create_custom_agreement( + &prosumer4, + &prosumer5, + 200, + 30, + setup.get_future_deadline(), + ).unwrap(); + + let agreement_id3 = setup.create_custom_agreement( + &setup.prosumer3, + &prosumer4, + 150, + 40, + setup.get_future_deadline(), + ).unwrap(); + + // All should have unique IDs + assert_ne!(agreement_id1, agreement_id2); + assert_ne!(agreement_id2, agreement_id3); + assert_ne!(agreement_id1, agreement_id3); + } + + #[test] + fn test_dispute_transaction() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + // This function doesn't exist in the current implementation, + // but would be part of a dispute resolution system + // setup.client.dispute_transaction(&transaction_id, &setup.consumer).unwrap(); + + // For now, we'll just verify the transaction exists and can be disputed + let transaction = setup.client.get_transaction(&transaction_id).unwrap(); + assert_eq!(transaction.status, TransactionStatus::Delivered); + } + + #[test] + fn test_unauthorized_settlement_attempts() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + // Generate random unauthorized user + let unauthorized_user = setup.env.generate::
(); + + let result = setup.client.settle_payment(&transaction_id, &unauthorized_user); + assert_eq!(result.unwrap_err(), SharingError::NotAuthorized); + } + + #[test] + fn test_agreement_expiry_edge_cases() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + // Advance time to exactly the deadline + setup.advance_ledger_time(86400); // Exactly 1 day + + // Try to deliver at exactly the deadline + let result = setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.provider, + ); + + // Should fail as deadline has passed + assert_eq!(result.unwrap_err(), SharingError::DeliveryDeadlinePassed); + } + + #[test] + fn test_large_meter_readings() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let large_meter_reading = u64::MAX; + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &100u64, + &large_meter_reading, + &setup.provider, + ).unwrap(); + + let transaction = setup.client.get_transaction(&transaction_id).unwrap(); + assert_eq!(transaction.meter_reading, large_meter_reading); + } + + #[test] + fn test_prosumer_acting_as_both_provider_and_consumer() { + let setup = TestSetup::new(); + + // Provider creates agreement to sell energy + let agreement_id1 = setup.create_custom_agreement( + &setup.provider, + &setup.consumer, + 100, + 50, + setup.get_future_deadline(), + ).unwrap(); + + // Same prosumer (provider) creates agreement to buy energy from another prosumer + let agreement_id2 = setup.create_custom_agreement( + &setup.prosumer3, + &setup.provider, // provider is now consumer + 150, + 40, + setup.get_future_deadline(), + ).unwrap(); + + // Both agreements should be valid + let agreement1 = setup.client.get_agreement(&agreement_id1).unwrap(); + let agreement2 = setup.client.get_agreement(&agreement_id2).unwrap(); + + assert_eq!(agreement1.provider, setup.provider); + assert_eq!(agreement2.consumer, setup.provider); + } + + #[test] + fn test_chain_of_energy_transactions() { + let setup = TestSetup::new(); + + // Create a chain: provider -> prosumer3 -> consumer + let agreement_id1 = setup.create_custom_agreement( + &setup.provider, + &setup.prosumer3, + 100, + 50, + setup.get_future_deadline(), + ).unwrap(); + + let agreement_id2 = setup.create_custom_agreement( + &setup.prosumer3, + &setup.consumer, + 100, + 60, // Higher price in second transaction + setup.get_future_deadline(), + ).unwrap(); + + // Execute both transactions + let transaction_id1 = setup.client.deliver_energy( + &agreement_id1, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + let transaction_id2 = setup.client.deliver_energy( + &agreement_id2, + &100u64, + &1500u64, + &setup.prosumer3, + ).unwrap(); + + // Settle both payments + setup.client.settle_payment(&transaction_id1, &setup.prosumer3).unwrap(); + setup.client.settle_payment(&transaction_id2, &setup.consumer).unwrap(); + + // Verify prosumer3 transaction history shows both transactions + let history = setup.client.get_transaction_history(&setup.prosumer3).unwrap(); + assert_eq!(history.len(), 2); + } +} \ No newline at end of file From 9528d7251929869677f13cc0c1748def39c393c6 Mon Sep 17 00:00:00 2001 From: SuperFranky Date: Tue, 7 Oct 2025 09:31:18 +0100 Subject: [PATCH 05/11] delivery and payment tests --- .../src/tests/delivery.rs | 291 ++++++++++++++ .../src/tests/payment.rs | 366 ++++++++++++++++++ 2 files changed, 657 insertions(+) create mode 100644 soroban/contracts/peer-to-peer-energy-sharing/src/tests/delivery.rs create mode 100644 soroban/contracts/peer-to-peer-energy-sharing/src/tests/payment.rs diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/delivery.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/delivery.rs new file mode 100644 index 0000000..f7760c0 --- /dev/null +++ b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/delivery.rs @@ -0,0 +1,291 @@ +#![cfg(test)] + +use crate::tests::utils::*; +use crate::utils::*; +use soroban_sdk::testutils::Address as _; + +#[test] +fn test_successful_energy_delivery() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &100u64, // Full energy amount + &1500u64, // Meter reading + &setup.provider, + ).unwrap(); + + assert_eq!(transaction_id, 1); + + let transaction = setup.client.get_transaction(&transaction_id).unwrap(); + assert_eq!(transaction.agreement_id, agreement_id); + assert_eq!(transaction.provider, setup.provider); + assert_eq!(transaction.consumer, setup.consumer); + assert_eq!(transaction.energy_delivered_kwh, 100); + assert_eq!(transaction.meter_reading, 1500); + assert_eq!(transaction.payment_amount, 5000); // 100 * 50 + assert_eq!(transaction.status, TransactionStatus::Delivered); + assert!(transaction.settled_at.is_none()); +} + +#[test] +fn test_partial_energy_delivery() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &75u64, // Partial delivery (75 out of 100 kWh) + &1125u64, // Meter reading + &setup.provider, + ).unwrap(); + + let transaction = setup.client.get_transaction(&transaction_id).unwrap(); + assert_eq!(transaction.energy_delivered_kwh, 75); + assert_eq!(transaction.payment_amount, 3750); // 75 * 50 +} + +#[test] +fn test_deliver_energy_unauthorized_provider() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let result = setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.consumer, // Wrong address - should be provider + ); + + assert_eq!(result.unwrap_err(), SharingError::NotAuthorized); +} + +#[test] +fn test_deliver_energy_nonexistent_agreement() { + let setup = TestSetup::new(); + + let result = setup.client.deliver_energy( + &999u64, // Non-existent agreement + &100u64, + &1500u64, + &setup.provider, + ); + + assert_eq!(result.unwrap_err(), SharingError::AgreementNotFound); +} + +#[test] +fn test_deliver_more_energy_than_agreed() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); // 100 kWh agreed + + let result = setup.client.deliver_energy( + &agreement_id, + &150u64, // More than agreed amount + &2250u64, + &setup.provider, + ); + + assert_eq!(result.unwrap_err(), SharingError::InsufficientEnergy); +} + +#[test] +fn test_deliver_energy_after_deadline() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + // Advance time beyond deadline + setup.advance_ledger_time(90000); // More than 1 day + + let result = setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.provider, + ); + + assert_eq!(result.unwrap_err(), SharingError::DeliveryDeadlinePassed); + + // Verify agreement status was updated to expired + let agreement = setup.client.get_agreement(&agreement_id).unwrap(); + assert_eq!(agreement.status, AgreementStatus::Expired); +} + +#[test] +fn test_deliver_energy_to_inactive_agreement() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + // First delivery + setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + // Try to deliver again - agreement is now in "Delivered" status + let result = setup.client.deliver_energy( + &agreement_id, + &50u64, + &750u64, + &setup.provider, + ); + + assert_eq!(result.unwrap_err(), SharingError::AgreementNotActive); +} + +#[test] +fn test_delivery_updates_agreement_status() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + // Check initial status + let agreement = setup.client.get_agreement(&agreement_id).unwrap(); + assert_eq!(agreement.status, AgreementStatus::Active); + + // Deliver energy + setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + // Check updated status + let agreement = setup.client.get_agreement(&agreement_id).unwrap(); + assert_eq!(agreement.status, AgreementStatus::Delivered); +} + +#[test] +fn test_multiple_deliveries_different_agreements() { + let setup = TestSetup::new(); + let agreement_id1 = setup.create_test_agreement().unwrap(); + let agreement_id2 = setup.create_custom_agreement( + &setup.prosumer3, + &setup.consumer, + 200, + 30, + setup.get_future_deadline(), + ).unwrap(); + + let transaction_id1 = setup.client.deliver_energy( + &agreement_id1, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + let transaction_id2 = setup.client.deliver_energy( + &agreement_id2, + &200u64, + &3000u64, + &setup.prosumer3, + ).unwrap(); + + assert_eq!(transaction_id1, 1); + assert_eq!(transaction_id2, 2); + + let transaction1 = setup.client.get_transaction(&transaction_id1).unwrap(); + let transaction2 = setup.client.get_transaction(&transaction_id2).unwrap(); + + assert_eq!(transaction1.agreement_id, agreement_id1); + assert_eq!(transaction2.agreement_id, agreement_id2); + assert_eq!(transaction1.energy_delivered_kwh, 100); + assert_eq!(transaction2.energy_delivered_kwh, 200); +} + +#[test] +fn test_delivery_timestamp_recorded() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let delivery_time = setup.env.ledger().timestamp(); + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + let transaction = setup.client.get_transaction(&transaction_id).unwrap(); + assert_eq!(transaction.delivered_at, delivery_time); +} + +#[test] +fn test_meter_reading_verification() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let meter_reading = 2750u64; + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &100u64, + &meter_reading, + &setup.provider, + ).unwrap(); + + let transaction = setup.client.get_transaction(&transaction_id).unwrap(); + assert_eq!(transaction.meter_reading, meter_reading); +} + +#[test] +fn test_zero_energy_delivery() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &0u64, // Zero energy delivery + &0u64, + &setup.provider, + ).unwrap(); + + let transaction = setup.client.get_transaction(&transaction_id).unwrap(); + assert_eq!(transaction.energy_delivered_kwh, 0); + assert_eq!(transaction.payment_amount, 0); +} + +#[test] +fn test_get_nonexistent_transaction() { + let setup = TestSetup::new(); + + let result = setup.client.get_transaction(&999); + assert_eq!(result.unwrap_err(), SharingError::TransactionNotFound); +} + +#[test] +fn test_transaction_data_integrity() { + let setup = TestSetup::new(); + let agreement_id = setup.create_custom_agreement( + &setup.provider, + &setup.consumer, + 250, + 80, + setup.get_future_deadline(), + ).unwrap(); + + let energy_delivered = 200u64; + let meter_reading = 4000u64; + let expected_payment = energy_delivered * 80; // price_per_kwh + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &energy_delivered, + &meter_reading, + &setup.provider, + ).unwrap(); + + let transaction = setup.client.get_transaction(&transaction_id).unwrap(); + + assert_eq!(transaction.transaction_id, transaction_id); + assert_eq!(transaction.agreement_id, agreement_id); + assert_eq!(transaction.provider, setup.provider); + assert_eq!(transaction.consumer, setup.consumer); + assert_eq!(transaction.energy_delivered_kwh, energy_delivered); + assert_eq!(transaction.meter_reading, meter_reading); + assert_eq!(transaction.payment_amount, expected_payment); + assert_eq!(transaction.status, TransactionStatus::Delivered); + assert!(transaction.settled_at.is_none()); +} \ No newline at end of file diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/payment.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/payment.rs new file mode 100644 index 0000000..49a6bfe --- /dev/null +++ b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/payment.rs @@ -0,0 +1,366 @@ +#![cfg(test)] + +use crate::tests::utils::*; +use crate::utils::*; +use soroban_sdk::testutils::Address as _; + +#[test] +fn test_successful_payment_settlement() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + // Deliver energy first + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + // Check initial balances + let consumer_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); + let provider_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); + + // Settle payment + setup.client.settle_payment(&transaction_id, &setup.consumer).unwrap(); + + // Check balances after payment + let consumer_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); + let provider_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); + + // Verify payment was transferred + assert_eq!(consumer_balance_after, consumer_balance_before - 5000); // 100 * 50 + assert_eq!(provider_balance_after, provider_balance_before + 5000); + + // Check transaction status updated + let transaction = setup.client.get_transaction(&transaction_id).unwrap(); + assert_eq!(transaction.status, TransactionStatus::Settled); + assert!(transaction.settled_at.is_some()); +} + +#[test] +fn test_provider_can_settle_payment() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + // Provider settles the payment + setup.client.settle_payment(&transaction_id, &setup.provider).unwrap(); + + let transaction = setup.client.get_transaction(&transaction_id).unwrap(); + assert_eq!(transaction.status, TransactionStatus::Settled); +} + +#[test] +fn test_settle_payment_unauthorized() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + // Unauthorized third party tries to settle + let result = setup.client.settle_payment(&transaction_id, &setup.prosumer3); + assert_eq!(result.unwrap_err(), SharingError::NotAuthorized); +} + +#[test] +fn test_settle_nonexistent_transaction() { + let setup = TestSetup::new(); + + let result = setup.client.settle_payment(&999, &setup.consumer); + assert_eq!(result.unwrap_err(), SharingError::TransactionNotFound); +} + +#[test] +fn test_settle_already_settled_transaction() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + // First settlement + setup.client.settle_payment(&transaction_id, &setup.consumer).unwrap(); + + // Try to settle again + let result = setup.client.settle_payment(&transaction_id, &setup.consumer); + assert_eq!(result.unwrap_err(), SharingError::TransactionAlreadySettled); +} + +#[test] +fn test_settle_payment_for_pending_transaction() { + let setup = TestSetup::new(); + + // Create a transaction ID that doesn't exist (simulating pending state) + let result = setup.client.settle_payment(&1, &setup.consumer); + assert_eq!(result.unwrap_err(), SharingError::TransactionNotFound); +} + +#[test] +fn test_payment_settlement_updates_agreement_status() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + // Check agreement status before settlement + let agreement = setup.client.get_agreement(&agreement_id).unwrap(); + assert_eq!(agreement.status, AgreementStatus::Delivered); + + // Settle payment + setup.client.settle_payment(&transaction_id, &setup.consumer).unwrap(); + + // Check agreement status after settlement + let agreement = setup.client.get_agreement(&agreement_id).unwrap(); + assert_eq!(agreement.status, AgreementStatus::Settled); +} + +#[test] +fn test_partial_delivery_payment() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); // 100 kWh at 50 per kWh + + // Partial delivery + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &75u64, // Only 75 kWh delivered + &1125u64, + &setup.provider, + ).unwrap(); + + let consumer_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); + let provider_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); + + setup.client.settle_payment(&transaction_id, &setup.consumer).unwrap(); + + let consumer_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); + let provider_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); + + // Should only pay for delivered amount: 75 * 50 = 3750 + assert_eq!(consumer_balance_after, consumer_balance_before - 3750); + assert_eq!(provider_balance_after, provider_balance_before + 3750); +} + +#[test] +fn test_zero_energy_delivery_payment() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &0u64, // Zero energy delivered + &0u64, + &setup.provider, + ).unwrap(); + + let consumer_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); + let provider_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); + + setup.client.settle_payment(&transaction_id, &setup.consumer).unwrap(); + + let consumer_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); + let provider_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); + + // No payment should occur for zero delivery + assert_eq!(consumer_balance_after, consumer_balance_before); + assert_eq!(provider_balance_after, provider_balance_before); +} + +#[test] +fn test_payment_settlement_timestamp() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + let settlement_time = setup.env.ledger().timestamp(); + setup.client.settle_payment(&transaction_id, &setup.consumer).unwrap(); + + let transaction = setup.client.get_transaction(&transaction_id).unwrap(); + assert_eq!(transaction.settled_at, Some(settlement_time)); +} + +#[test] +fn test_multiple_payment_settlements() { + let setup = TestSetup::new(); + + // Create two agreements + let agreement_id1 = setup.create_test_agreement().unwrap(); + let agreement_id2 = setup.create_custom_agreement( + &setup.prosumer3, + &setup.consumer, + 200, + 30, + setup.get_future_deadline(), + ).unwrap(); + + // Deliver energy for both + let transaction_id1 = setup.client.deliver_energy( + &agreement_id1, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + let transaction_id2 = setup.client.deliver_energy( + &agreement_id2, + &200u64, + &3000u64, + &setup.prosumer3, + ).unwrap(); + + let consumer_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); + let provider_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); + let prosumer3_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.prosumer3); + + // Settle both payments + setup.client.settle_payment(&transaction_id1, &setup.consumer).unwrap(); + setup.client.settle_payment(&transaction_id2, &setup.consumer).unwrap(); + + let consumer_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); + let provider_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); + let prosumer3_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.prosumer3); + + // Check all balances updated correctly + assert_eq!(consumer_balance_after, consumer_balance_before - 5000 - 6000); // 5000 + 6000 + assert_eq!(provider_balance_after, provider_balance_before + 5000); + assert_eq!(prosumer3_balance_after, prosumer3_balance_before + 6000); +} + +#[test] +fn test_get_transaction_history_empty() { + let setup = TestSetup::new(); + + let history = setup.client.get_transaction_history(&setup.provider).unwrap(); + assert_eq!(history.len(), 0); +} + +#[test] +fn test_get_transaction_history_provider() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + let history = setup.client.get_transaction_history(&setup.provider).unwrap(); + assert_eq!(history.len(), 1); + assert_eq!(history.get(0).unwrap().transaction_id, transaction_id); +} + +#[test] +fn test_get_transaction_history_consumer() { + let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement().unwrap(); + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + let history = setup.client.get_transaction_history(&setup.consumer).unwrap(); + assert_eq!(history.len(), 1); + assert_eq!(history.get(0).unwrap().transaction_id, transaction_id); +} + +#[test] +fn test_get_transaction_history_multiple_transactions() { + let setup = TestSetup::new(); + + // Create multiple agreements and transactions + let agreement_id1 = setup.create_test_agreement().unwrap(); + let agreement_id2 = setup.create_custom_agreement( + &setup.provider, + &setup.prosumer3, + 150, + 40, + setup.get_future_deadline(), + ).unwrap(); + + setup.client.deliver_energy( + &agreement_id1, + &100u64, + &1500u64, + &setup.provider, + ).unwrap(); + + setup.client.deliver_energy( + &agreement_id2, + &150u64, + &2250u64, + &setup.provider, + ).unwrap(); + + let history = setup.client.get_transaction_history(&setup.provider).unwrap(); + assert_eq!(history.len(), 2); + + // Consumer should only see their transaction + let consumer_history = setup.client.get_transaction_history(&setup.consumer).unwrap(); + assert_eq!(consumer_history.len(), 1); + + // Prosumer3 should only see their transaction + let prosumer3_history = setup.client.get_transaction_history(&setup.prosumer3).unwrap(); + assert_eq!(prosumer3_history.len(), 1); +} + +#[test] +fn test_payment_accuracy_with_different_prices() { + let setup = TestSetup::new(); + let agreement_id = setup.create_custom_agreement( + &setup.provider, + &setup.consumer, + 250, + 120, // Higher price per kWh + setup.get_future_deadline(), + ).unwrap(); + + let transaction_id = setup.client.deliver_energy( + &agreement_id, + &200u64, // 200 out of 250 kWh + &3000u64, + &setup.provider, + ).unwrap(); + + let consumer_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); + let provider_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); + + setup.client.settle_payment(&transaction_id, &setup.consumer).unwrap(); + + let consumer_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); + let provider_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); + + // Payment should be: 200 * 120 = 24000 + assert_eq!(consumer_balance_after, consumer_balance_before - 24000); + assert_eq!(provider_balance_after, provider_balance_before + 24000); +} \ No newline at end of file From aa8ef4be920106b1569c0e59b16edb335fb10051 Mon Sep 17 00:00:00 2001 From: SuperFranky Date: Tue, 7 Oct 2025 11:24:32 +0100 Subject: [PATCH 06/11] removed old test files --- .../peer-to-peer-energy-sharing/src/test.rs | 336 ------------------ 1 file changed, 336 deletions(-) delete mode 100644 soroban/contracts/peer-to-peer-energy-sharing/src/test.rs diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/test.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/test.rs deleted file mode 100644 index 11fd57e..0000000 --- a/soroban/contracts/peer-to-peer-energy-sharing/src/test.rs +++ /dev/null @@ -1,336 +0,0 @@ -#[cfg(test)] -mod tests; - -#[cfg(test)] -mod edge_cases_security { - use super::tests::utils::*; - use crate::utils::*; - use soroban_sdk::{testutils::Address as _, Env}; - - #[test] - fn test_contract_initialization_twice() { - let setup = TestSetup::new(); - - // Try to initialize again - let result = setup.client.initialize(&setup.admin, &setup.token_contract); - assert_eq!(result.unwrap_err(), SharingError::AlreadyInitialized); - } - - #[test] - fn test_register_prosumer_twice() { - let setup = TestSetup::new(); - - // Try to register the same prosumer again - let result = setup.client.register_prosumer(&setup.provider); - assert!(result.is_ok()); // Should succeed (idempotent operation) - } - - #[test] - fn test_high_volume_agreements() { - let setup = TestSetup::new(); - let mut agreement_ids = Vec::new(); - - // Create 100 agreements - for i in 0..100 { - let energy_amount = 50 + (i % 200); - let price = 25 + (i % 100); - - let agreement_id = setup.create_custom_agreement( - &setup.provider, - &setup.consumer, - energy_amount as u64, - price as u64, - setup.get_future_deadline(), - ).unwrap(); - - agreement_ids.push(agreement_id); - } - - // Verify all agreements were created with sequential IDs - assert_eq!(agreement_ids.len(), 100); - for (i, &id) in agreement_ids.iter().enumerate() { - assert_eq!(id, (i + 1) as u64); - } - } - - #[test] - fn test_high_volume_transactions() { - let setup = TestSetup::new(); - let mut transaction_ids = Vec::new(); - - // Create multiple agreements and deliver energy for each - for i in 0..50 { - let agreement_id = setup.create_custom_agreement( - &setup.provider, - &setup.consumer, - 100, - 50, - setup.get_future_deadline(), - ).unwrap(); - - let transaction_id = setup.client.deliver_energy( - &agreement_id, - &(50 + (i % 50)), - &(1000 + i * 100), - &setup.provider, - ).unwrap(); - - transaction_ids.push(transaction_id); - } - - // Verify all transactions were created - assert_eq!(transaction_ids.len(), 50); - - // Verify transaction history contains all transactions - let history = setup.client.get_transaction_history(&setup.provider).unwrap(); - assert_eq!(history.len(), 50); - } - - #[test] - fn test_maximum_energy_amounts() { - let setup = TestSetup::new(); - - let max_energy = u64::MAX; - let price = 1u64; - - // This might overflow in total_amount calculation, but should be handled - let result = setup.create_custom_agreement( - &setup.provider, - &setup.consumer, - max_energy, - price, - setup.get_future_deadline(), - ); - - // Should either succeed or fail gracefully - match result { - Ok(agreement_id) => { - let agreement = setup.client.get_agreement(&agreement_id).unwrap(); - assert_eq!(agreement.energy_amount_kwh, max_energy); - } - Err(_) => { - // Acceptable if the contract prevents overflow - } - } - } - - #[test] - fn test_edge_case_deadlines() { - let setup = TestSetup::new(); - - // Test with deadline exactly at current time + 1 second - let near_future_deadline = setup.env.ledger().timestamp() + 1; - - let agreement_id = setup.create_custom_agreement( - &setup.provider, - &setup.consumer, - 100, - 50, - near_future_deadline, - ).unwrap(); - - // Should be able to deliver immediately - let transaction_id = setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); - - assert_eq!(transaction_id, 1); - } - - #[test] - fn test_concurrent_operations_different_prosumers() { - let setup = TestSetup::new(); - - // Register additional prosumers - let prosumer4 = setup.env.generate::
(); - let prosumer5 = setup.env.generate::
(); - setup.client.register_prosumer(&prosumer4).unwrap(); - setup.client.register_prosumer(&prosumer5).unwrap(); - - // Create multiple agreements simultaneously - let agreement_id1 = setup.create_custom_agreement( - &setup.provider, - &setup.consumer, - 100, - 50, - setup.get_future_deadline(), - ).unwrap(); - - let agreement_id2 = setup.create_custom_agreement( - &prosumer4, - &prosumer5, - 200, - 30, - setup.get_future_deadline(), - ).unwrap(); - - let agreement_id3 = setup.create_custom_agreement( - &setup.prosumer3, - &prosumer4, - 150, - 40, - setup.get_future_deadline(), - ).unwrap(); - - // All should have unique IDs - assert_ne!(agreement_id1, agreement_id2); - assert_ne!(agreement_id2, agreement_id3); - assert_ne!(agreement_id1, agreement_id3); - } - - #[test] - fn test_dispute_transaction() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); - - let transaction_id = setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); - - // This function doesn't exist in the current implementation, - // but would be part of a dispute resolution system - // setup.client.dispute_transaction(&transaction_id, &setup.consumer).unwrap(); - - // For now, we'll just verify the transaction exists and can be disputed - let transaction = setup.client.get_transaction(&transaction_id).unwrap(); - assert_eq!(transaction.status, TransactionStatus::Delivered); - } - - #[test] - fn test_unauthorized_settlement_attempts() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); - - let transaction_id = setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); - - // Generate random unauthorized user - let unauthorized_user = setup.env.generate::
(); - - let result = setup.client.settle_payment(&transaction_id, &unauthorized_user); - assert_eq!(result.unwrap_err(), SharingError::NotAuthorized); - } - - #[test] - fn test_agreement_expiry_edge_cases() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); - - // Advance time to exactly the deadline - setup.advance_ledger_time(86400); // Exactly 1 day - - // Try to deliver at exactly the deadline - let result = setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.provider, - ); - - // Should fail as deadline has passed - assert_eq!(result.unwrap_err(), SharingError::DeliveryDeadlinePassed); - } - - #[test] - fn test_large_meter_readings() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); - - let large_meter_reading = u64::MAX; - - let transaction_id = setup.client.deliver_energy( - &agreement_id, - &100u64, - &large_meter_reading, - &setup.provider, - ).unwrap(); - - let transaction = setup.client.get_transaction(&transaction_id).unwrap(); - assert_eq!(transaction.meter_reading, large_meter_reading); - } - - #[test] - fn test_prosumer_acting_as_both_provider_and_consumer() { - let setup = TestSetup::new(); - - // Provider creates agreement to sell energy - let agreement_id1 = setup.create_custom_agreement( - &setup.provider, - &setup.consumer, - 100, - 50, - setup.get_future_deadline(), - ).unwrap(); - - // Same prosumer (provider) creates agreement to buy energy from another prosumer - let agreement_id2 = setup.create_custom_agreement( - &setup.prosumer3, - &setup.provider, // provider is now consumer - 150, - 40, - setup.get_future_deadline(), - ).unwrap(); - - // Both agreements should be valid - let agreement1 = setup.client.get_agreement(&agreement_id1).unwrap(); - let agreement2 = setup.client.get_agreement(&agreement_id2).unwrap(); - - assert_eq!(agreement1.provider, setup.provider); - assert_eq!(agreement2.consumer, setup.provider); - } - - #[test] - fn test_chain_of_energy_transactions() { - let setup = TestSetup::new(); - - // Create a chain: provider -> prosumer3 -> consumer - let agreement_id1 = setup.create_custom_agreement( - &setup.provider, - &setup.prosumer3, - 100, - 50, - setup.get_future_deadline(), - ).unwrap(); - - let agreement_id2 = setup.create_custom_agreement( - &setup.prosumer3, - &setup.consumer, - 100, - 60, // Higher price in second transaction - setup.get_future_deadline(), - ).unwrap(); - - // Execute both transactions - let transaction_id1 = setup.client.deliver_energy( - &agreement_id1, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); - - let transaction_id2 = setup.client.deliver_energy( - &agreement_id2, - &100u64, - &1500u64, - &setup.prosumer3, - ).unwrap(); - - // Settle both payments - setup.client.settle_payment(&transaction_id1, &setup.prosumer3).unwrap(); - setup.client.settle_payment(&transaction_id2, &setup.consumer).unwrap(); - - // Verify prosumer3 transaction history shows both transactions - let history = setup.client.get_transaction_history(&setup.prosumer3).unwrap(); - assert_eq!(history.len(), 2); - } -} \ No newline at end of file From 12ecdfff037765cc7a93a98130e570ae2dda191d Mon Sep 17 00:00:00 2001 From: SuperFranky Date: Tue, 7 Oct 2025 11:24:45 +0100 Subject: [PATCH 07/11] modified agreement tests --- .../src/tests/agreement.rs | 242 +++--------------- 1 file changed, 35 insertions(+), 207 deletions(-) diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/agreement.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/agreement.rs index a0aa865..d9cc14d 100644 --- a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/agreement.rs +++ b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/agreement.rs @@ -2,246 +2,74 @@ use crate::tests::utils::*; use crate::utils::*; -use soroban_sdk::testutils::Address as _; +use crate::{PeerToPeerEnergySharing, PeerToPeerEnergySharingClient}; +use soroban_sdk::{testutils::Address as _, Address, Env}; #[test] -fn test_create_valid_agreement() { +fn test_valid_agreement_creation() { let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); - assert_eq!(agreement_id, 1); + let agreement_id = setup.create_test_agreement(); + let agreement = setup.client.get_agreement(&agreement_id); - let agreement = setup.client.get_agreement(&agreement_id).unwrap(); + // Verify data integrity assert_eq!(agreement.provider, setup.provider); assert_eq!(agreement.consumer, setup.consumer); assert_eq!(agreement.energy_amount_kwh, 100); assert_eq!(agreement.price_per_kwh, 50); - assert_eq!(agreement.total_amount, 5000); // 100 * 50 + assert_eq!(agreement.total_amount, 5000); assert_eq!(agreement.status, AgreementStatus::Active); } #[test] -fn test_create_agreement_with_zero_energy() { +fn test_agreement_invalid_inputs() { let setup = TestSetup::new(); - let result = setup.create_custom_agreement( - &setup.provider, - &setup.consumer, - 0, // Zero energy - 50, - setup.get_future_deadline(), + // Zero energy amount + let result = setup.client.try_create_agreement( + &setup.provider, &setup.consumer, &0u64, &50u64, &setup.get_future_deadline() ); + assert_eq!(result, Err(Ok(SharingError::InvalidInput))); - assert_eq!(result.unwrap_err(), SharingError::InvalidInput); -} - -#[test] -fn test_create_agreement_with_zero_price() { - let setup = TestSetup::new(); - - let result = setup.create_custom_agreement( - &setup.provider, - &setup.consumer, - 100, - 0, // Zero price - setup.get_future_deadline(), - ); - - assert_eq!(result.unwrap_err(), SharingError::InvalidInput); -} - -#[test] -fn test_create_agreement_with_past_deadline() { - let setup = TestSetup::new(); - - let past_deadline = setup.env.ledger().timestamp() - 3600; // 1 hour ago - - let result = setup.create_custom_agreement( - &setup.provider, - &setup.consumer, - 100, - 50, - past_deadline, + // Zero price + let result = setup.client.try_create_agreement( + &setup.provider, &setup.consumer, &100u64, &0u64, &setup.get_future_deadline() ); + assert_eq!(result, Err(Ok(SharingError::InvalidInput))); - assert_eq!(result.unwrap_err(), SharingError::DeliveryDeadlinePassed); -} - -#[test] -fn test_self_sharing_not_allowed() { - let setup = TestSetup::new(); - - let result = setup.create_custom_agreement( - &setup.provider, - &setup.provider, // Same as provider - 100, - 50, - setup.get_future_deadline(), + // Invalid deadline + let result = setup.client.try_create_agreement( + &setup.provider, &setup.consumer, &100u64, &50u64, &0u64 ); - - assert_eq!(result.unwrap_err(), SharingError::SelfSharingNotAllowed); + assert_eq!(result, Err(Ok(SharingError::InvalidInput))); } #[test] -fn test_unregistered_prosumer_provider() { +fn test_agreement_authorization_failures() { let setup = TestSetup::new(); - let unregistered = setup.env.generate::
(); + let unregistered = Address::generate(&setup.env); - let result = setup.create_custom_agreement( - &unregistered, - &setup.consumer, - 100, - 50, - setup.get_future_deadline(), + // Unregistered provider + let result = setup.client.try_create_agreement( + &unregistered, &setup.consumer, &100u64, &50u64, &setup.get_future_deadline() ); + assert_eq!(result, Err(Ok(SharingError::ProsumerNotRegistered))); - assert_eq!(result.unwrap_err(), SharingError::ProsumerNotRegistered); -} - -#[test] -fn test_unregistered_prosumer_consumer() { - let setup = TestSetup::new(); - let unregistered = setup.env.generate::
(); - - let result = setup.create_custom_agreement( - &setup.provider, - &unregistered, - 100, - 50, - setup.get_future_deadline(), + // Self-sharing not allowed + let result = setup.client.try_create_agreement( + &setup.provider, &setup.provider, &100u64, &50u64, &setup.get_future_deadline() ); + assert_eq!(result, Err(Ok(SharingError::SelfSharingNotAllowed))); - assert_eq!(result.unwrap_err(), SharingError::ProsumerNotRegistered); -} - -#[test] -fn test_multiple_agreements_increment_ids() { - let setup = TestSetup::new(); - - let id1 = setup.create_test_agreement().unwrap(); - let id2 = setup.create_custom_agreement( - &setup.prosumer3, - &setup.consumer, - 200, - 30, - setup.get_future_deadline(), - ).unwrap(); - let id3 = setup.create_custom_agreement( - &setup.provider, - &setup.prosumer3, - 50, - 100, - setup.get_future_deadline(), - ).unwrap(); - - assert_eq!(id1, 1); - assert_eq!(id2, 2); - assert_eq!(id3, 3); -} - -#[test] -fn test_agreement_total_amount_calculation() { - let setup = TestSetup::new(); - - let agreement_id = setup.create_custom_agreement( - &setup.provider, - &setup.consumer, - 250, // energy_amount_kwh - 75, // price_per_kwh - setup.get_future_deadline(), - ).unwrap(); - - let agreement = setup.client.get_agreement(&agreement_id).unwrap(); - assert_eq!(agreement.total_amount, 18750); // 250 * 75 -} - -#[test] -fn test_agreement_created_timestamp() { - let setup = TestSetup::new(); - - let current_time = setup.env.ledger().timestamp(); - let agreement_id = setup.create_test_agreement().unwrap(); - - let agreement = setup.client.get_agreement(&agreement_id).unwrap(); - assert_eq!(agreement.created_at, current_time); -} - -#[test] -fn test_get_nonexistent_agreement() { - let setup = TestSetup::new(); - - let result = setup.client.get_agreement(&999); - assert_eq!(result.unwrap_err(), SharingError::AgreementNotFound); -} - -#[test] -fn test_agreement_data_integrity() { - let setup = TestSetup::new(); - - let energy_amount = 150u64; - let price = 80u64; - let deadline = setup.get_future_deadline(); - - let agreement_id = setup.create_custom_agreement( - &setup.provider, - &setup.consumer, - energy_amount, - price, - deadline, - ).unwrap(); - - let agreement = setup.client.get_agreement(&agreement_id).unwrap(); - - // Verify all data integrity - assert_eq!(agreement.agreement_id, agreement_id); - assert_eq!(agreement.provider, setup.provider); - assert_eq!(agreement.consumer, setup.consumer); - assert_eq!(agreement.energy_amount_kwh, energy_amount); - assert_eq!(agreement.price_per_kwh, price); - assert_eq!(agreement.total_amount, energy_amount * price); - assert_eq!(agreement.delivery_deadline, deadline); - assert_eq!(agreement.status, AgreementStatus::Active); -} - -#[test] -fn test_large_energy_amounts() { - let setup = TestSetup::new(); - - let large_energy = 1_000_000u64; - let price = 100u64; - - let agreement_id = setup.create_custom_agreement( - &setup.provider, - &setup.consumer, - large_energy, - price, - setup.get_future_deadline(), - ).unwrap(); - - let agreement = setup.client.get_agreement(&agreement_id).unwrap(); - assert_eq!(agreement.energy_amount_kwh, large_energy); - assert_eq!(agreement.total_amount, large_energy * price); -} - -#[test] -fn test_contract_not_initialized() { + // Contract not initialized let env = Env::default(); env.mock_all_auths(); - let contract_id = env.register(PeerToPeerEnergySharing, ()); let client = PeerToPeerEnergySharingClient::new(&env, &contract_id); - let provider = env.generate::
(); - let consumer = env.generate::
(); - - // Try to create agreement without initialization - let result = client.create_agreement( - &provider, - &consumer, - &100u64, - &50u64, - &(env.ledger().timestamp() + 86400), + let result = client.try_create_agreement( + &Address::generate(&env), &Address::generate(&env), + &100u64, &50u64, &(env.ledger().timestamp() + 86400) ); - - assert_eq!(result.unwrap_err(), SharingError::NotInitialized); + assert_eq!(result, Err(Ok(SharingError::NotInitialized))); } \ No newline at end of file From 95ff73d9e36b9067449751bfaccdbd4383f68c8a Mon Sep 17 00:00:00 2001 From: SuperFranky Date: Tue, 7 Oct 2025 11:24:53 +0100 Subject: [PATCH 08/11] modify delivery tests --- .../src/tests/delivery.rs | 288 +++--------------- 1 file changed, 38 insertions(+), 250 deletions(-) diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/delivery.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/delivery.rs index f7760c0..2ce3d9e 100644 --- a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/delivery.rs +++ b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/delivery.rs @@ -2,290 +2,78 @@ use crate::tests::utils::*; use crate::utils::*; -use soroban_sdk::testutils::Address as _; #[test] -fn test_successful_energy_delivery() { +fn test_valid_energy_delivery() { let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); + let agreement_id = setup.create_test_agreement(); let transaction_id = setup.client.deliver_energy( - &agreement_id, - &100u64, // Full energy amount - &1500u64, // Meter reading - &setup.provider, - ).unwrap(); - - assert_eq!(transaction_id, 1); + &agreement_id, &100u64, &1500u64, &setup.provider + ); - let transaction = setup.client.get_transaction(&transaction_id).unwrap(); - assert_eq!(transaction.agreement_id, agreement_id); - assert_eq!(transaction.provider, setup.provider); - assert_eq!(transaction.consumer, setup.consumer); + let transaction = setup.client.get_transaction(&transaction_id); assert_eq!(transaction.energy_delivered_kwh, 100); assert_eq!(transaction.meter_reading, 1500); - assert_eq!(transaction.payment_amount, 5000); // 100 * 50 + assert_eq!(transaction.payment_amount, 5000); assert_eq!(transaction.status, TransactionStatus::Delivered); - assert!(transaction.settled_at.is_none()); -} - -#[test] -fn test_partial_energy_delivery() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); - let transaction_id = setup.client.deliver_energy( - &agreement_id, - &75u64, // Partial delivery (75 out of 100 kWh) - &1125u64, // Meter reading - &setup.provider, - ).unwrap(); - - let transaction = setup.client.get_transaction(&transaction_id).unwrap(); - assert_eq!(transaction.energy_delivered_kwh, 75); - assert_eq!(transaction.payment_amount, 3750); // 75 * 50 + // Verify agreement status updated + let agreement = setup.client.get_agreement(&agreement_id); + assert_eq!(agreement.status, AgreementStatus::Delivered); } #[test] -fn test_deliver_energy_unauthorized_provider() { +fn test_delivery_validation_failures() { let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); + let agreement_id = setup.create_test_agreement(); - let result = setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.consumer, // Wrong address - should be provider + // Unauthorized provider + let result = setup.client.try_deliver_energy( + &agreement_id, &100u64, &1500u64, &setup.consumer ); + assert_eq!(result, Err(Ok(SharingError::NotAuthorized))); - assert_eq!(result.unwrap_err(), SharingError::NotAuthorized); -} - -#[test] -fn test_deliver_energy_nonexistent_agreement() { - let setup = TestSetup::new(); - - let result = setup.client.deliver_energy( - &999u64, // Non-existent agreement - &100u64, - &1500u64, - &setup.provider, + // Excessive energy delivery + let result = setup.client.try_deliver_energy( + &agreement_id, &150u64, &2250u64, &setup.provider ); + assert_eq!(result, Err(Ok(SharingError::InsufficientEnergy))); - assert_eq!(result.unwrap_err(), SharingError::AgreementNotFound); -} - -#[test] -fn test_deliver_more_energy_than_agreed() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); // 100 kWh agreed - - let result = setup.client.deliver_energy( - &agreement_id, - &150u64, // More than agreed amount - &2250u64, - &setup.provider, + // Non-existent agreement + let result = setup.client.try_deliver_energy( + &999u64, &100u64, &1500u64, &setup.provider ); - - assert_eq!(result.unwrap_err(), SharingError::InsufficientEnergy); -} - -#[test] -fn test_deliver_energy_after_deadline() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); - - // Advance time beyond deadline - setup.advance_ledger_time(90000); // More than 1 day - - let result = setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.provider, - ); - - assert_eq!(result.unwrap_err(), SharingError::DeliveryDeadlinePassed); - - // Verify agreement status was updated to expired - let agreement = setup.client.get_agreement(&agreement_id).unwrap(); - assert_eq!(agreement.status, AgreementStatus::Expired); + assert_eq!(result, Err(Ok(SharingError::AgreementNotFound))); } #[test] -fn test_deliver_energy_to_inactive_agreement() { +fn test_delivery_deadline_enforcement() { let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); + let agreement_id = setup.create_test_agreement(); - // First delivery - setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); + // Advance time past deadline + setup.advance_ledger_time(90000); - // Try to deliver again - agreement is now in "Delivered" status - let result = setup.client.deliver_energy( - &agreement_id, - &50u64, - &750u64, - &setup.provider, + let result = setup.client.try_deliver_energy( + &agreement_id, &100u64, &1500u64, &setup.provider ); - - assert_eq!(result.unwrap_err(), SharingError::AgreementNotActive); -} - -#[test] -fn test_delivery_updates_agreement_status() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); - - // Check initial status - let agreement = setup.client.get_agreement(&agreement_id).unwrap(); - assert_eq!(agreement.status, AgreementStatus::Active); - - // Deliver energy - setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); - - // Check updated status - let agreement = setup.client.get_agreement(&agreement_id).unwrap(); - assert_eq!(agreement.status, AgreementStatus::Delivered); -} - -#[test] -fn test_multiple_deliveries_different_agreements() { - let setup = TestSetup::new(); - let agreement_id1 = setup.create_test_agreement().unwrap(); - let agreement_id2 = setup.create_custom_agreement( - &setup.prosumer3, - &setup.consumer, - 200, - 30, - setup.get_future_deadline(), - ).unwrap(); - - let transaction_id1 = setup.client.deliver_energy( - &agreement_id1, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); - - let transaction_id2 = setup.client.deliver_energy( - &agreement_id2, - &200u64, - &3000u64, - &setup.prosumer3, - ).unwrap(); - - assert_eq!(transaction_id1, 1); - assert_eq!(transaction_id2, 2); - - let transaction1 = setup.client.get_transaction(&transaction_id1).unwrap(); - let transaction2 = setup.client.get_transaction(&transaction_id2).unwrap(); - - assert_eq!(transaction1.agreement_id, agreement_id1); - assert_eq!(transaction2.agreement_id, agreement_id2); - assert_eq!(transaction1.energy_delivered_kwh, 100); - assert_eq!(transaction2.energy_delivered_kwh, 200); + assert_eq!(result, Err(Ok(SharingError::DeliveryDeadlinePassed))); } #[test] -fn test_delivery_timestamp_recorded() { +fn test_partial_delivery_with_meter_verification() { let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); - - let delivery_time = setup.env.ledger().timestamp(); - let transaction_id = setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); - - let transaction = setup.client.get_transaction(&transaction_id).unwrap(); - assert_eq!(transaction.delivered_at, delivery_time); -} - -#[test] -fn test_meter_reading_verification() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); + let agreement_id = setup.create_test_agreement(); + // Partial delivery with specific meter reading let meter_reading = 2750u64; let transaction_id = setup.client.deliver_energy( - &agreement_id, - &100u64, - &meter_reading, - &setup.provider, - ).unwrap(); - - let transaction = setup.client.get_transaction(&transaction_id).unwrap(); - assert_eq!(transaction.meter_reading, meter_reading); -} - -#[test] -fn test_zero_energy_delivery() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); - - let transaction_id = setup.client.deliver_energy( - &agreement_id, - &0u64, // Zero energy delivery - &0u64, - &setup.provider, - ).unwrap(); - - let transaction = setup.client.get_transaction(&transaction_id).unwrap(); - assert_eq!(transaction.energy_delivered_kwh, 0); - assert_eq!(transaction.payment_amount, 0); -} - -#[test] -fn test_get_nonexistent_transaction() { - let setup = TestSetup::new(); - - let result = setup.client.get_transaction(&999); - assert_eq!(result.unwrap_err(), SharingError::TransactionNotFound); -} - -#[test] -fn test_transaction_data_integrity() { - let setup = TestSetup::new(); - let agreement_id = setup.create_custom_agreement( - &setup.provider, - &setup.consumer, - 250, - 80, - setup.get_future_deadline(), - ).unwrap(); - - let energy_delivered = 200u64; - let meter_reading = 4000u64; - let expected_payment = energy_delivered * 80; // price_per_kwh - - let transaction_id = setup.client.deliver_energy( - &agreement_id, - &energy_delivered, - &meter_reading, - &setup.provider, - ).unwrap(); - - let transaction = setup.client.get_transaction(&transaction_id).unwrap(); + &agreement_id, &75u64, &meter_reading, &setup.provider + ); - assert_eq!(transaction.transaction_id, transaction_id); - assert_eq!(transaction.agreement_id, agreement_id); - assert_eq!(transaction.provider, setup.provider); - assert_eq!(transaction.consumer, setup.consumer); - assert_eq!(transaction.energy_delivered_kwh, energy_delivered); + let transaction = setup.client.get_transaction(&transaction_id); + assert_eq!(transaction.energy_delivered_kwh, 75); assert_eq!(transaction.meter_reading, meter_reading); - assert_eq!(transaction.payment_amount, expected_payment); - assert_eq!(transaction.status, TransactionStatus::Delivered); - assert!(transaction.settled_at.is_none()); + assert_eq!(transaction.payment_amount, 3750); // 75 * 50 } \ No newline at end of file From af80177a999527e34a4e644724e1d245675f52b3 Mon Sep 17 00:00:00 2001 From: SuperFranky Date: Tue, 7 Oct 2025 11:25:14 +0100 Subject: [PATCH 09/11] modified payment test, removed redundancies and repeat tests --- .../src/tests/payment.rs | 355 +++--------------- 1 file changed, 50 insertions(+), 305 deletions(-) diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/payment.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/payment.rs index 49a6bfe..0a5ffe0 100644 --- a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/payment.rs +++ b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/payment.rs @@ -2,365 +2,110 @@ use crate::tests::utils::*; use crate::utils::*; -use soroban_sdk::testutils::Address as _; #[test] fn test_successful_payment_settlement() { let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); + let agreement_id = setup.create_test_agreement(); - // Deliver energy first + // Deliver energy let transaction_id = setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); + &agreement_id, &100u64, &1500u64, &setup.provider + ); - // Check initial balances + // Check balances before settlement let consumer_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); let provider_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); // Settle payment - setup.client.settle_payment(&transaction_id, &setup.consumer).unwrap(); + setup.client.settle_payment(&transaction_id, &setup.consumer); - // Check balances after payment + // Verify payment transferred correctly let consumer_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); let provider_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); - // Verify payment was transferred - assert_eq!(consumer_balance_after, consumer_balance_before - 5000); // 100 * 50 + assert_eq!(consumer_balance_after, consumer_balance_before - 5000); assert_eq!(provider_balance_after, provider_balance_before + 5000); - // Check transaction status updated - let transaction = setup.client.get_transaction(&transaction_id).unwrap(); + // Verify transaction and agreement status updated + let transaction = setup.client.get_transaction(&transaction_id); assert_eq!(transaction.status, TransactionStatus::Settled); assert!(transaction.settled_at.is_some()); -} - -#[test] -fn test_provider_can_settle_payment() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); - - let transaction_id = setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); - - // Provider settles the payment - setup.client.settle_payment(&transaction_id, &setup.provider).unwrap(); - - let transaction = setup.client.get_transaction(&transaction_id).unwrap(); - assert_eq!(transaction.status, TransactionStatus::Settled); -} - -#[test] -fn test_settle_payment_unauthorized() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); - - let transaction_id = setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); - - // Unauthorized third party tries to settle - let result = setup.client.settle_payment(&transaction_id, &setup.prosumer3); - assert_eq!(result.unwrap_err(), SharingError::NotAuthorized); -} - -#[test] -fn test_settle_nonexistent_transaction() { - let setup = TestSetup::new(); - - let result = setup.client.settle_payment(&999, &setup.consumer); - assert_eq!(result.unwrap_err(), SharingError::TransactionNotFound); -} - -#[test] -fn test_settle_already_settled_transaction() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); - - let transaction_id = setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); - - // First settlement - setup.client.settle_payment(&transaction_id, &setup.consumer).unwrap(); - // Try to settle again - let result = setup.client.settle_payment(&transaction_id, &setup.consumer); - assert_eq!(result.unwrap_err(), SharingError::TransactionAlreadySettled); -} - -#[test] -fn test_settle_payment_for_pending_transaction() { - let setup = TestSetup::new(); - - // Create a transaction ID that doesn't exist (simulating pending state) - let result = setup.client.settle_payment(&1, &setup.consumer); - assert_eq!(result.unwrap_err(), SharingError::TransactionNotFound); -} - -#[test] -fn test_payment_settlement_updates_agreement_status() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); - - let transaction_id = setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); - - // Check agreement status before settlement - let agreement = setup.client.get_agreement(&agreement_id).unwrap(); - assert_eq!(agreement.status, AgreementStatus::Delivered); - - // Settle payment - setup.client.settle_payment(&transaction_id, &setup.consumer).unwrap(); - - // Check agreement status after settlement - let agreement = setup.client.get_agreement(&agreement_id).unwrap(); + let agreement = setup.client.get_agreement(&agreement_id); assert_eq!(agreement.status, AgreementStatus::Settled); } #[test] -fn test_partial_delivery_payment() { +fn test_payment_authorization_failures() { let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); // 100 kWh at 50 per kWh + let agreement_id = setup.create_test_agreement(); - // Partial delivery let transaction_id = setup.client.deliver_energy( - &agreement_id, - &75u64, // Only 75 kWh delivered - &1125u64, - &setup.provider, - ).unwrap(); + &agreement_id, &100u64, &1500u64, &setup.provider + ); - let consumer_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); - let provider_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); + // Unauthorized settlement attempt + let result = setup.client.try_settle_payment(&transaction_id, &setup.prosumer3); + assert_eq!(result, Err(Ok(SharingError::NotAuthorized))); - setup.client.settle_payment(&transaction_id, &setup.consumer).unwrap(); + // Non-existent transaction + let result = setup.client.try_settle_payment(&999, &setup.consumer); + assert_eq!(result, Err(Ok(SharingError::TransactionNotFound))); - let consumer_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); - let provider_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); + // Settle successfully first time + setup.client.settle_payment(&transaction_id, &setup.consumer); - // Should only pay for delivered amount: 75 * 50 = 3750 - assert_eq!(consumer_balance_after, consumer_balance_before - 3750); - assert_eq!(provider_balance_after, provider_balance_before + 3750); + // Duplicate settlement attempt + let result = setup.client.try_settle_payment(&transaction_id, &setup.consumer); + assert_eq!(result, Err(Ok(SharingError::TransactionAlreadySettled))); } #[test] -fn test_zero_energy_delivery_payment() { +fn test_payment_accuracy_partial_delivery() { let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); - - let transaction_id = setup.client.deliver_energy( - &agreement_id, - &0u64, // Zero energy delivered - &0u64, - &setup.provider, - ).unwrap(); - - let consumer_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); - let provider_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); - - setup.client.settle_payment(&transaction_id, &setup.consumer).unwrap(); - - let consumer_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); - let provider_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); - - // No payment should occur for zero delivery - assert_eq!(consumer_balance_after, consumer_balance_before); - assert_eq!(provider_balance_after, provider_balance_before); -} - -#[test] -fn test_payment_settlement_timestamp() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); + let agreement_id = setup.create_custom_agreement( + &setup.provider, &setup.consumer, 250, 120, setup.get_future_deadline() + ); + // Partial delivery: 200 out of 250 kWh at 120 per kWh let transaction_id = setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); - - let settlement_time = setup.env.ledger().timestamp(); - setup.client.settle_payment(&transaction_id, &setup.consumer).unwrap(); - - let transaction = setup.client.get_transaction(&transaction_id).unwrap(); - assert_eq!(transaction.settled_at, Some(settlement_time)); -} - -#[test] -fn test_multiple_payment_settlements() { - let setup = TestSetup::new(); - - // Create two agreements - let agreement_id1 = setup.create_test_agreement().unwrap(); - let agreement_id2 = setup.create_custom_agreement( - &setup.prosumer3, - &setup.consumer, - 200, - 30, - setup.get_future_deadline(), - ).unwrap(); - - // Deliver energy for both - let transaction_id1 = setup.client.deliver_energy( - &agreement_id1, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); - - let transaction_id2 = setup.client.deliver_energy( - &agreement_id2, - &200u64, - &3000u64, - &setup.prosumer3, - ).unwrap(); + &agreement_id, &200u64, &3000u64, &setup.provider + ); let consumer_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); let provider_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); - let prosumer3_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.prosumer3); - // Settle both payments - setup.client.settle_payment(&transaction_id1, &setup.consumer).unwrap(); - setup.client.settle_payment(&transaction_id2, &setup.consumer).unwrap(); + setup.client.settle_payment(&transaction_id, &setup.provider); let consumer_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); let provider_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); - let prosumer3_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.prosumer3); - // Check all balances updated correctly - assert_eq!(consumer_balance_after, consumer_balance_before - 5000 - 6000); // 5000 + 6000 - assert_eq!(provider_balance_after, provider_balance_before + 5000); - assert_eq!(prosumer3_balance_after, prosumer3_balance_before + 6000); + // Should pay exactly: 200 * 120 = 24000 + assert_eq!(consumer_balance_after, consumer_balance_before - 24000); + assert_eq!(provider_balance_after, provider_balance_before + 24000); } #[test] -fn test_get_transaction_history_empty() { +fn test_transaction_history_tracking() { let setup = TestSetup::new(); + let agreement_id = setup.create_test_agreement(); - let history = setup.client.get_transaction_history(&setup.provider).unwrap(); + // Initially empty + let history = setup.client.get_transaction_history(&setup.provider); assert_eq!(history.len(), 0); -} - -#[test] -fn test_get_transaction_history_provider() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); + // Create transaction let transaction_id = setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); + &agreement_id, &100u64, &1500u64, &setup.provider + ); - let history = setup.client.get_transaction_history(&setup.provider).unwrap(); - assert_eq!(history.len(), 1); - assert_eq!(history.get(0).unwrap().transaction_id, transaction_id); -} - -#[test] -fn test_get_transaction_history_consumer() { - let setup = TestSetup::new(); - let agreement_id = setup.create_test_agreement().unwrap(); - - let transaction_id = setup.client.deliver_energy( - &agreement_id, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); + // Verify transaction appears in both provider and consumer history + let provider_history = setup.client.get_transaction_history(&setup.provider); + let consumer_history = setup.client.get_transaction_history(&setup.consumer); - let history = setup.client.get_transaction_history(&setup.consumer).unwrap(); - assert_eq!(history.len(), 1); - assert_eq!(history.get(0).unwrap().transaction_id, transaction_id); -} - -#[test] -fn test_get_transaction_history_multiple_transactions() { - let setup = TestSetup::new(); - - // Create multiple agreements and transactions - let agreement_id1 = setup.create_test_agreement().unwrap(); - let agreement_id2 = setup.create_custom_agreement( - &setup.provider, - &setup.prosumer3, - 150, - 40, - setup.get_future_deadline(), - ).unwrap(); - - setup.client.deliver_energy( - &agreement_id1, - &100u64, - &1500u64, - &setup.provider, - ).unwrap(); - - setup.client.deliver_energy( - &agreement_id2, - &150u64, - &2250u64, - &setup.provider, - ).unwrap(); - - let history = setup.client.get_transaction_history(&setup.provider).unwrap(); - assert_eq!(history.len(), 2); - - // Consumer should only see their transaction - let consumer_history = setup.client.get_transaction_history(&setup.consumer).unwrap(); + assert_eq!(provider_history.len(), 1); assert_eq!(consumer_history.len(), 1); - - // Prosumer3 should only see their transaction - let prosumer3_history = setup.client.get_transaction_history(&setup.prosumer3).unwrap(); - assert_eq!(prosumer3_history.len(), 1); -} - -#[test] -fn test_payment_accuracy_with_different_prices() { - let setup = TestSetup::new(); - let agreement_id = setup.create_custom_agreement( - &setup.provider, - &setup.consumer, - 250, - 120, // Higher price per kWh - setup.get_future_deadline(), - ).unwrap(); - - let transaction_id = setup.client.deliver_energy( - &agreement_id, - &200u64, // 200 out of 250 kWh - &3000u64, - &setup.provider, - ).unwrap(); - - let consumer_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); - let provider_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); - - setup.client.settle_payment(&transaction_id, &setup.consumer).unwrap(); - - let consumer_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); - let provider_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); - - // Payment should be: 200 * 120 = 24000 - assert_eq!(consumer_balance_after, consumer_balance_before - 24000); - assert_eq!(provider_balance_after, provider_balance_before + 24000); + assert_eq!(provider_history.get(0).unwrap().transaction_id, transaction_id); + assert_eq!(consumer_history.get(0).unwrap().transaction_id, transaction_id); } \ No newline at end of file From ad53245381cc8aee1ec3c47d92b07ebfe6338659 Mon Sep 17 00:00:00 2001 From: SuperFranky Date: Tue, 7 Oct 2025 11:25:21 +0100 Subject: [PATCH 10/11] utils --- .../peer-to-peer-energy-sharing/src/tests/utils.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/utils.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/utils.rs index 19c8b53..115571c 100644 --- a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/utils.rs +++ b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/utils.rs @@ -1,7 +1,7 @@ #![cfg(test)] use crate::{PeerToPeerEnergySharing, PeerToPeerEnergySharingClient, utils::*}; -use soroban_sdk::{testutils::Address as _, Address, Env}; +use soroban_sdk::{testutils::{Address as _, Ledger}, Address, Env}; pub struct TestSetup { pub env: Env, @@ -28,12 +28,12 @@ impl TestSetup { let client = PeerToPeerEnergySharingClient::new(&env, &contract_id); // Initialize contract - client.initialize(&admin, &token_contract).unwrap(); + client.initialize(&admin, &token_contract); // Register prosumers - client.register_prosumer(&provider).unwrap(); - client.register_prosumer(&consumer).unwrap(); - client.register_prosumer(&prosumer3).unwrap(); + client.register_prosumer(&provider); + client.register_prosumer(&consumer); + client.register_prosumer(&prosumer3); // Mint tokens for testing payments mint_tokens(&env, &token_contract, &admin, &consumer, 10_000_000); @@ -58,7 +58,7 @@ impl TestSetup { self.env.ledger().timestamp() + 86400 // 1 day from now } - pub fn create_test_agreement(&self) -> Result { + pub fn create_test_agreement(&self) -> u64 { self.client.create_agreement( &self.provider, &self.consumer, @@ -75,7 +75,7 @@ impl TestSetup { energy_amount: u64, price_per_kwh: u64, deadline: u64, - ) -> Result { + ) -> u64 { self.client.create_agreement( provider, consumer, From 6c01d23b0f739d72241e761e894993d22a7b7885 Mon Sep 17 00:00:00 2001 From: SuperFranky Date: Tue, 7 Oct 2025 11:25:48 +0100 Subject: [PATCH 11/11] ran cargo fmt --- .../src/tests/agreement.rs | 58 +++++--- .../src/tests/delivery.rs | 60 ++++---- .../src/tests/mod.rs | 4 +- .../src/tests/payment.rs | 132 +++++++++++------- .../src/tests/utils.rs | 28 ++-- 5 files changed, 171 insertions(+), 111 deletions(-) diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/agreement.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/agreement.rs index d9cc14d..b9801cc 100644 --- a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/agreement.rs +++ b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/agreement.rs @@ -8,10 +8,10 @@ use soroban_sdk::{testutils::Address as _, Address, Env}; #[test] fn test_valid_agreement_creation() { let setup = TestSetup::new(); - + let agreement_id = setup.create_test_agreement(); let agreement = setup.client.get_agreement(&agreement_id); - + // Verify data integrity assert_eq!(agreement.provider, setup.provider); assert_eq!(agreement.consumer, setup.consumer); @@ -24,23 +24,32 @@ fn test_valid_agreement_creation() { #[test] fn test_agreement_invalid_inputs() { let setup = TestSetup::new(); - + // Zero energy amount let result = setup.client.try_create_agreement( - &setup.provider, &setup.consumer, &0u64, &50u64, &setup.get_future_deadline() + &setup.provider, + &setup.consumer, + &0u64, + &50u64, + &setup.get_future_deadline(), ); assert_eq!(result, Err(Ok(SharingError::InvalidInput))); - + // Zero price let result = setup.client.try_create_agreement( - &setup.provider, &setup.consumer, &100u64, &0u64, &setup.get_future_deadline() + &setup.provider, + &setup.consumer, + &100u64, + &0u64, + &setup.get_future_deadline(), ); assert_eq!(result, Err(Ok(SharingError::InvalidInput))); - + // Invalid deadline - let result = setup.client.try_create_agreement( - &setup.provider, &setup.consumer, &100u64, &50u64, &0u64 - ); + let result = + setup + .client + .try_create_agreement(&setup.provider, &setup.consumer, &100u64, &50u64, &0u64); assert_eq!(result, Err(Ok(SharingError::InvalidInput))); } @@ -48,28 +57,39 @@ fn test_agreement_invalid_inputs() { fn test_agreement_authorization_failures() { let setup = TestSetup::new(); let unregistered = Address::generate(&setup.env); - + // Unregistered provider let result = setup.client.try_create_agreement( - &unregistered, &setup.consumer, &100u64, &50u64, &setup.get_future_deadline() + &unregistered, + &setup.consumer, + &100u64, + &50u64, + &setup.get_future_deadline(), ); assert_eq!(result, Err(Ok(SharingError::ProsumerNotRegistered))); - + // Self-sharing not allowed let result = setup.client.try_create_agreement( - &setup.provider, &setup.provider, &100u64, &50u64, &setup.get_future_deadline() + &setup.provider, + &setup.provider, + &100u64, + &50u64, + &setup.get_future_deadline(), ); assert_eq!(result, Err(Ok(SharingError::SelfSharingNotAllowed))); - + // Contract not initialized let env = Env::default(); env.mock_all_auths(); let contract_id = env.register(PeerToPeerEnergySharing, ()); let client = PeerToPeerEnergySharingClient::new(&env, &contract_id); - + let result = client.try_create_agreement( - &Address::generate(&env), &Address::generate(&env), - &100u64, &50u64, &(env.ledger().timestamp() + 86400) + &Address::generate(&env), + &Address::generate(&env), + &100u64, + &50u64, + &(env.ledger().timestamp() + 86400), ); assert_eq!(result, Err(Ok(SharingError::NotInitialized))); -} \ No newline at end of file +} diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/delivery.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/delivery.rs index 2ce3d9e..442eb57 100644 --- a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/delivery.rs +++ b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/delivery.rs @@ -7,17 +7,18 @@ use crate::utils::*; fn test_valid_energy_delivery() { let setup = TestSetup::new(); let agreement_id = setup.create_test_agreement(); - - let transaction_id = setup.client.deliver_energy( - &agreement_id, &100u64, &1500u64, &setup.provider - ); - + + let transaction_id = + setup + .client + .deliver_energy(&agreement_id, &100u64, &1500u64, &setup.provider); + let transaction = setup.client.get_transaction(&transaction_id); assert_eq!(transaction.energy_delivered_kwh, 100); assert_eq!(transaction.meter_reading, 1500); assert_eq!(transaction.payment_amount, 5000); assert_eq!(transaction.status, TransactionStatus::Delivered); - + // Verify agreement status updated let agreement = setup.client.get_agreement(&agreement_id); assert_eq!(agreement.status, AgreementStatus::Delivered); @@ -27,23 +28,23 @@ fn test_valid_energy_delivery() { fn test_delivery_validation_failures() { let setup = TestSetup::new(); let agreement_id = setup.create_test_agreement(); - + // Unauthorized provider - let result = setup.client.try_deliver_energy( - &agreement_id, &100u64, &1500u64, &setup.consumer - ); + let result = setup + .client + .try_deliver_energy(&agreement_id, &100u64, &1500u64, &setup.consumer); assert_eq!(result, Err(Ok(SharingError::NotAuthorized))); - + // Excessive energy delivery - let result = setup.client.try_deliver_energy( - &agreement_id, &150u64, &2250u64, &setup.provider - ); + let result = setup + .client + .try_deliver_energy(&agreement_id, &150u64, &2250u64, &setup.provider); assert_eq!(result, Err(Ok(SharingError::InsufficientEnergy))); - + // Non-existent agreement - let result = setup.client.try_deliver_energy( - &999u64, &100u64, &1500u64, &setup.provider - ); + let result = setup + .client + .try_deliver_energy(&999u64, &100u64, &1500u64, &setup.provider); assert_eq!(result, Err(Ok(SharingError::AgreementNotFound))); } @@ -51,13 +52,13 @@ fn test_delivery_validation_failures() { fn test_delivery_deadline_enforcement() { let setup = TestSetup::new(); let agreement_id = setup.create_test_agreement(); - + // Advance time past deadline setup.advance_ledger_time(90000); - - let result = setup.client.try_deliver_energy( - &agreement_id, &100u64, &1500u64, &setup.provider - ); + + let result = setup + .client + .try_deliver_energy(&agreement_id, &100u64, &1500u64, &setup.provider); assert_eq!(result, Err(Ok(SharingError::DeliveryDeadlinePassed))); } @@ -65,15 +66,16 @@ fn test_delivery_deadline_enforcement() { fn test_partial_delivery_with_meter_verification() { let setup = TestSetup::new(); let agreement_id = setup.create_test_agreement(); - + // Partial delivery with specific meter reading let meter_reading = 2750u64; - let transaction_id = setup.client.deliver_energy( - &agreement_id, &75u64, &meter_reading, &setup.provider - ); - + let transaction_id = + setup + .client + .deliver_energy(&agreement_id, &75u64, &meter_reading, &setup.provider); + let transaction = setup.client.get_transaction(&transaction_id); assert_eq!(transaction.energy_delivered_kwh, 75); assert_eq!(transaction.meter_reading, meter_reading); assert_eq!(transaction.payment_amount, 3750); // 75 * 50 -} \ No newline at end of file +} diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/mod.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/mod.rs index b39495e..19c8f03 100644 --- a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/mod.rs +++ b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/mod.rs @@ -1,6 +1,6 @@ #![cfg(test)] -pub mod utils; pub mod agreement; pub mod delivery; -pub mod payment; \ No newline at end of file +pub mod payment; +pub mod utils; diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/payment.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/payment.rs index 0a5ffe0..d316f7e 100644 --- a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/payment.rs +++ b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/payment.rs @@ -7,31 +7,38 @@ use crate::utils::*; fn test_successful_payment_settlement() { let setup = TestSetup::new(); let agreement_id = setup.create_test_agreement(); - + // Deliver energy - let transaction_id = setup.client.deliver_energy( - &agreement_id, &100u64, &1500u64, &setup.provider - ); - + let transaction_id = + setup + .client + .deliver_energy(&agreement_id, &100u64, &1500u64, &setup.provider); + // Check balances before settlement - let consumer_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); - let provider_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); - + let consumer_balance_before = + get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); + let provider_balance_before = + get_token_balance(&setup.env, &setup.token_contract, &setup.provider); + // Settle payment - setup.client.settle_payment(&transaction_id, &setup.consumer); - + setup + .client + .settle_payment(&transaction_id, &setup.consumer); + // Verify payment transferred correctly - let consumer_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); - let provider_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); - + let consumer_balance_after = + get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); + let provider_balance_after = + get_token_balance(&setup.env, &setup.token_contract, &setup.provider); + assert_eq!(consumer_balance_after, consumer_balance_before - 5000); assert_eq!(provider_balance_after, provider_balance_before + 5000); - + // Verify transaction and agreement status updated let transaction = setup.client.get_transaction(&transaction_id); assert_eq!(transaction.status, TransactionStatus::Settled); assert!(transaction.settled_at.is_some()); - + let agreement = setup.client.get_agreement(&agreement_id); assert_eq!(agreement.status, AgreementStatus::Settled); } @@ -40,24 +47,31 @@ fn test_successful_payment_settlement() { fn test_payment_authorization_failures() { let setup = TestSetup::new(); let agreement_id = setup.create_test_agreement(); - - let transaction_id = setup.client.deliver_energy( - &agreement_id, &100u64, &1500u64, &setup.provider - ); - + + let transaction_id = + setup + .client + .deliver_energy(&agreement_id, &100u64, &1500u64, &setup.provider); + // Unauthorized settlement attempt - let result = setup.client.try_settle_payment(&transaction_id, &setup.prosumer3); + let result = setup + .client + .try_settle_payment(&transaction_id, &setup.prosumer3); assert_eq!(result, Err(Ok(SharingError::NotAuthorized))); - + // Non-existent transaction let result = setup.client.try_settle_payment(&999, &setup.consumer); assert_eq!(result, Err(Ok(SharingError::TransactionNotFound))); - + // Settle successfully first time - setup.client.settle_payment(&transaction_id, &setup.consumer); - + setup + .client + .settle_payment(&transaction_id, &setup.consumer); + // Duplicate settlement attempt - let result = setup.client.try_settle_payment(&transaction_id, &setup.consumer); + let result = setup + .client + .try_settle_payment(&transaction_id, &setup.consumer); assert_eq!(result, Err(Ok(SharingError::TransactionAlreadySettled))); } @@ -65,22 +79,33 @@ fn test_payment_authorization_failures() { fn test_payment_accuracy_partial_delivery() { let setup = TestSetup::new(); let agreement_id = setup.create_custom_agreement( - &setup.provider, &setup.consumer, 250, 120, setup.get_future_deadline() + &setup.provider, + &setup.consumer, + 250, + 120, + setup.get_future_deadline(), ); - + // Partial delivery: 200 out of 250 kWh at 120 per kWh - let transaction_id = setup.client.deliver_energy( - &agreement_id, &200u64, &3000u64, &setup.provider - ); - - let consumer_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); - let provider_balance_before = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); - - setup.client.settle_payment(&transaction_id, &setup.provider); - - let consumer_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); - let provider_balance_after = get_token_balance(&setup.env, &setup.token_contract, &setup.provider); - + let transaction_id = + setup + .client + .deliver_energy(&agreement_id, &200u64, &3000u64, &setup.provider); + + let consumer_balance_before = + get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); + let provider_balance_before = + get_token_balance(&setup.env, &setup.token_contract, &setup.provider); + + setup + .client + .settle_payment(&transaction_id, &setup.provider); + + let consumer_balance_after = + get_token_balance(&setup.env, &setup.token_contract, &setup.consumer); + let provider_balance_after = + get_token_balance(&setup.env, &setup.token_contract, &setup.provider); + // Should pay exactly: 200 * 120 = 24000 assert_eq!(consumer_balance_after, consumer_balance_before - 24000); assert_eq!(provider_balance_after, provider_balance_before + 24000); @@ -90,22 +115,29 @@ fn test_payment_accuracy_partial_delivery() { fn test_transaction_history_tracking() { let setup = TestSetup::new(); let agreement_id = setup.create_test_agreement(); - + // Initially empty let history = setup.client.get_transaction_history(&setup.provider); assert_eq!(history.len(), 0); - + // Create transaction - let transaction_id = setup.client.deliver_energy( - &agreement_id, &100u64, &1500u64, &setup.provider - ); - + let transaction_id = + setup + .client + .deliver_energy(&agreement_id, &100u64, &1500u64, &setup.provider); + // Verify transaction appears in both provider and consumer history let provider_history = setup.client.get_transaction_history(&setup.provider); let consumer_history = setup.client.get_transaction_history(&setup.consumer); - + assert_eq!(provider_history.len(), 1); assert_eq!(consumer_history.len(), 1); - assert_eq!(provider_history.get(0).unwrap().transaction_id, transaction_id); - assert_eq!(consumer_history.get(0).unwrap().transaction_id, transaction_id); -} \ No newline at end of file + assert_eq!( + provider_history.get(0).unwrap().transaction_id, + transaction_id + ); + assert_eq!( + consumer_history.get(0).unwrap().transaction_id, + transaction_id + ); +} diff --git a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/utils.rs b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/utils.rs index 115571c..10e33c3 100644 --- a/soroban/contracts/peer-to-peer-energy-sharing/src/tests/utils.rs +++ b/soroban/contracts/peer-to-peer-energy-sharing/src/tests/utils.rs @@ -1,7 +1,10 @@ #![cfg(test)] -use crate::{PeerToPeerEnergySharing, PeerToPeerEnergySharingClient, utils::*}; -use soroban_sdk::{testutils::{Address as _, Ledger}, Address, Env}; +use crate::{utils::*, PeerToPeerEnergySharing, PeerToPeerEnergySharingClient}; +use soroban_sdk::{ + testutils::{Address as _, Ledger}, + Address, Env, +}; pub struct TestSetup { pub env: Env, @@ -49,25 +52,27 @@ impl TestSetup { prosumer3, } } - + pub fn advance_ledger_time(&self, seconds: u64) { - self.env.ledger().set_timestamp(self.env.ledger().timestamp() + seconds); + self.env + .ledger() + .set_timestamp(self.env.ledger().timestamp() + seconds); } - + pub fn get_future_deadline(&self) -> u64 { self.env.ledger().timestamp() + 86400 // 1 day from now } - + pub fn create_test_agreement(&self) -> u64 { self.client.create_agreement( &self.provider, &self.consumer, - &100u64, // 100 kWh - &50u64, // 50 units per kWh + &100u64, // 100 kWh + &50u64, // 50 units per kWh &self.get_future_deadline(), ) } - + pub fn create_custom_agreement( &self, provider: &Address, @@ -87,7 +92,8 @@ impl TestSetup { } pub fn create_test_token(env: &Env, admin: &Address) -> Address { - env.register_stellar_asset_contract_v2(admin.clone()).address() + env.register_stellar_asset_contract_v2(admin.clone()) + .address() } pub fn mint_tokens( @@ -106,4 +112,4 @@ pub fn get_token_balance(env: &Env, token_address: &Address, account: &Address) use soroban_sdk::token; let token = token::Client::new(env, token_address); token.balance(account) -} \ No newline at end of file +}