-
Notifications
You must be signed in to change notification settings - Fork 134
Description
The dispute mechanism is the most nuanced part of the contract — it has a time-gated entry, a special Disputed status that blocks all other flows, and a two-outcome resolution. These six tests together form a complete behavioural specification: they verify the happy-path dispute, two ways the window can be closed, both resolution outcomes, and the guard preventing resolution of a non-disputed escrow.
Task
Building on the test file from Issue #3, add the following six tests:
-
test_raise_dispute_within_window— happy path:- Creates escrow, advances ledger by 1 hour (within 24-hour window)
- Depositor calls
raise_dispute - Asserts
escrow.status == EscrowStatus::Disputed - Asserts
escrow.dispute_raised_at.is_some()
-
test_raise_dispute_after_window_fails— guard: window expired:- Creates escrow, advances ledger by
DISPUTE_WINDOW + 1seconds - Depositor calls
raise_dispute - Expects panic
"Error(Contract, #8)"(DisputeWindowClosed)
- Creates escrow, advances ledger by
-
test_raise_dispute_when_window_zero_fails— guard: disputes disabled:- Initialises the contract with
dispute_window_secs = 0(bypasses theinithelper, usesPaymentEscrowContractClient::newdirectly) - Creates an escrow
- Depositor calls
raise_dispute - Expects panic
"Error(Contract, #8)"(DisputeWindowClosed)
- Initialises the contract with
-
test_resolve_dispute_releases_to_beneficiary— resolution outcome A:- Creates escrow, raises dispute, admin calls
resolve_disputewithrelease_to_beneficiary = true - Asserts beneficiary's balance is
5_000 - Asserts
escrow.status == EscrowStatus::Released
- Creates escrow, raises dispute, admin calls
-
test_resolve_dispute_refunds_to_depositor— resolution outcome B:- Creates escrow, raises dispute, admin calls
resolve_disputewithrelease_to_beneficiary = false - Asserts depositor's balance is restored to
10_000 - Asserts
escrow.status == EscrowStatus::Refunded
- Creates escrow, raises dispute, admin calls
-
test_resolve_dispute_on_pending_escrow_fails— guard: no dispute raised:- Creates escrow (status stays
Pending) - Admin calls
resolve_disputewithout raising a dispute first - Expects panic
"Error(Contract, #7)"(EscrowNotDisputed)
- Creates escrow (status stays
Files to Modify
contracts/payment_escrow/src/test.rs
Acceptance Criteria
- All six tests are present and correctly named
-
test_raise_dispute_within_windowusesadvance_time(&env, 3_600)before callingraise_dispute -
test_raise_dispute_after_window_failsadvances byDISPUTE_WINDOW + 1 -
test_raise_dispute_when_window_zero_failsinitialises with&0u64directly (not viainithelper) -
test_resolve_dispute_releases_to_beneficiarypasses&trueas the last argument -
test_resolve_dispute_refunds_to_depositorpasses&falseas the last argument -
test_resolve_dispute_on_pending_escrow_failsuses#[should_panic(expected = "Error(Contract, #7)")] -
cargo test -p payment_escrowruns 15 tests, all pass -
cargo clippy -p payment_escrow -- -D warningspasses
Technical Notes
resolve_disputetakes a&boolargument:client.resolve_dispute(&admin, &String::from_str(&env, "esc-001"), &true)- For test 3, call
client.initialize(&admin, &token, &0u64)directly instead of using theinithelper advance_timeis the helper defined in Issue FRONTEND: Setup Next.js 14 and Essential Frontend Dependencies #1 — use it, do not manually mutate the ledger inline