Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion soroban/contracts/peer-to-peer-energy-sharing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod sharing;
mod utils;

#[cfg(test)]
mod test;
mod tests;

use soroban_sdk::{contract, contractimpl, Address, Env, Map, Vec};

Expand Down
1 change: 0 additions & 1 deletion soroban/contracts/peer-to-peer-energy-sharing/src/test.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#![cfg(test)]

use crate::tests::utils::*;
use crate::utils::*;
use crate::{PeerToPeerEnergySharing, PeerToPeerEnergySharingClient};
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);
assert_eq!(agreement.energy_amount_kwh, 100);
assert_eq!(agreement.price_per_kwh, 50);
assert_eq!(agreement.total_amount, 5000);
assert_eq!(agreement.status, AgreementStatus::Active);
}

#[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(),
);
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(),
);
assert_eq!(result, Err(Ok(SharingError::InvalidInput)));

// Invalid deadline
let result =
setup
.client
.try_create_agreement(&setup.provider, &setup.consumer, &100u64, &50u64, &0u64);
assert_eq!(result, Err(Ok(SharingError::InvalidInput)));
}

#[test]
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(),
);
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(),
);
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),
);
assert_eq!(result, Err(Ok(SharingError::NotInitialized)));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#![cfg(test)]

use crate::tests::utils::*;
use crate::utils::*;

#[test]
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 = 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);
}

#[test]
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);
assert_eq!(result, Err(Ok(SharingError::NotAuthorized)));

// Excessive energy delivery
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);
assert_eq!(result, Err(Ok(SharingError::AgreementNotFound)));
}

#[test]
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);
assert_eq!(result, Err(Ok(SharingError::DeliveryDeadlinePassed)));
}

#[test]
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 = 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
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#![cfg(test)]

pub mod agreement;
pub mod delivery;
pub mod payment;
pub mod utils;
143 changes: 143 additions & 0 deletions soroban/contracts/peer-to-peer-energy-sharing/src/tests/payment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#![cfg(test)]

use crate::tests::utils::*;
use crate::utils::*;

#[test]
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);

// 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);

// 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);

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);
}

#[test]
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);

// Unauthorized settlement attempt
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);

// Duplicate settlement attempt
let result = setup
.client
.try_settle_payment(&transaction_id, &setup.consumer);
assert_eq!(result, Err(Ok(SharingError::TransactionAlreadySettled)));
}

#[test]
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(),
);

// 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);

// 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_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);

// 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
);
}
Loading