Skip to content

[good-first-issue] [Soroban] Write full test suite for SpendingPolicy contract #2

Description

@IyanuOluwaJesuloba

Summary

The Registry contract has tests in contracts/tests/registry_test.rs. However, the SpendingPolicy contract (contracts/src/policy.rs) has zero test coverage. This is a critical gap — the spending policy handles real USDC transfers and must be thoroughly tested before any testnet or mainnet deployment.

Background

The SpendingPolicy contract (contracts/src/policy.rs) has the following public functions that all need tests:

Functions: create_policy(), execute_payment(), revoke_policy(), get_policy(), is_authorized(), remaining_allowance()
The key error cases defined in PolicyError (line 21–29) also need negative tests:

rust

pub enum PolicyError {
    PolicyNotFound      = 1,
    NotOwner            = 2,
    PolicyInactive      = 3,
    ExceedsPerTxLimit   = 4,
    ExceedsDailyLimit   = 5,
    InvalidAmount       = 6,
    UnauthorizedAgent   = 7,
    RecipientNotAllowed = 8,
}

What Needs to Be Built

Create the file contracts/tests/policy_test.rs with the following test cases:

Happy path tests:

test_create_policy_success — create a policy, verify all fields are stored correctly

test_execute_payment_success — agent executes a payment within limits, verify token transfer happens

test_revoke_policy_success — owner revokes policy, verify is_active becomes false

test_remaining_allowance_full — new policy has full daily limit available

test_remaining_allowance_after_spend — after a payment, remaining allowance decreases correctly

test_daily_reset — advance ledger by 17,280+ sequences, verify spent_today resets to 0

test_is_authorized_true — correct agent returns true

test_is_authorized_false — wrong agent or inactive policy returns false

test_policy_count — increments correctly after each create_policy call

Error / negative tests:
10. test_payment_exceeds_per_tx_limit — amount > max_per_tx → ExceedsPerTxLimit
11. test_payment_exceeds_daily_limit — cumulative spend > daily_limit → ExceedsDailyLimit
12. test_payment_on_revoked_policy — execute_payment on inactive policy → PolicyInactive
13. test_revoke_nonexistent_policy → PolicyNotFound
14. test_payment_wrong_recipient — policy has allowed_recipient set, different address passed → RecipientNotAllowed
15. test_create_policy_zero_amount — max_per_tx = 0 → InvalidAmount

Relevant Files

File:

  • contracts/src/policy.rs: The contract being tested — read this carefully before writing tests
  • contracts/src/types.rs: SpendingPolicy, PaymentRecord, DataKey structs
  • contracts/tests/registry_test.rsReference — use the same test structure and helpers
  • contracts/Cargo.tomlAlready has soroban-sdk = { features = ["testutils"] } — no changes needed

How to Run Tests

bash

cd contracts
cargo test
# or to run only policy tests:
cargo test policy

Acceptance Criteria

File contracts/tests/policy_test.rs created

All 15 test cases listed above are implemented

All tests pass: cargo test returns 0 failures

No compiler warnings: cargo clippy -- -D warnings passes

Each test has a comment explaining what it's verifying

Tips

Look at how registry_test.rs uses Env::default(), env.register_contract(), and ContractClient — follow the same pattern

For testing token transfers, use soroban_sdk::testutils::token::Client to create a mock USDC token

For advancing ledgers (daily reset test), use env.ledger().with_mut(|l| l.sequence_number += 17_281)

The #[cfg(test)] attribute must be at the top of the test file

Estimated Effort

Medium (4–8 hours)

//Please don't submit a PR without being assigned.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions