Skip to content

test(coverage): add 9 test modules for contract test coverage push#54

Open
Josue19-08 wants to merge 2 commits into
boundlessfi:testnetfrom
Josue19-08:feat/issue-25-contract-test-coverage-push
Open

test(coverage): add 9 test modules for contract test coverage push#54
Josue19-08 wants to merge 2 commits into
boundlessfi:testnetfrom
Josue19-08:feat/issue-25-contract-test-coverage-push

Conversation

@Josue19-08

@Josue19-08 Josue19-08 commented Jun 24, 2026

Copy link
Copy Markdown

Description

Implements the full test coverage matrix described in #25. Adds 6 new test modules for boundless-events and 2 for boundless-profile (bounty_pillar and hackathon_pillar were already merged via #46 and #47; credits via #48).

Changes

boundless-events:

  • token_whitelistregister_supported_token, deregister_supported_token, create_event rejection of unsupported/deregistered tokens
  • cancel_refund — paged cancel flow: OwnerOnly, FullPartnerThenResidual, ProRata, pagination across batches, all error variants
  • escrow_fee_math — default fee, per-event override, add_funds rate snapshot, waiver (0 bps), MAX_FEE_BPS guard, single/60-40 payout math, admin fee update
  • grant_pillarMulti release required, fixed-split milestone math, last-milestone dust sweep, credit/rep side-effects, all error variants

boundless-profile:

  • earningsregister_earnings, zero/negative guard, multi-user/token tracking, i128::MAX saturation, op replay guard
  • reputationbump/slash/admin_slash, saturation, all error variants + op replay + auth

Result: 206 tests passing (145 events + 61 profile), zero warnings.

Closes

Closes #25

Notes

  • soroban_sdk::Vec shadows std::vec::Vec in test scope — array literals are used instead of .collect() to avoid the name collision.
  • Bounty, hackathon, and credits modules were already merged by other contributors; this PR adds the remaining modules to complete issue Epic: contract test-coverage push (events + profile) #25.

Summary by CodeRabbit

  • New Features

    • Added support for token whitelist management and stricter validation when creating events.
    • Expanded event flows to cover grant milestones, cancellation refunds, and escrow fee calculations.
    • Added profile earnings and reputation tracking coverage.
  • Bug Fixes

    • Tightened refund, payout, and cancellation behavior across multiple event types.
    • Improved handling of replayed operations, invalid submissions, and duplicate winner selection.
    • Clarified balance and status updates after milestone claims and event completion.

…coverage push

Implements the full test coverage matrix from issue boundlessfi#25:

events:
- token_whitelist: register/deregister token support + create_event gate
- cancel_refund: paged cancel flow (OwnerOnly, FullPartnerThenResidual,
  ProRata, pagination, all error variants)
- escrow_fee_math: fee override, waiver, add_funds rate snapshot,
  MAX_FEE_BPS guard, single/split payout math
- grant_pillar: Multi release required, fixed-split milestone math,
  last-milestone dust sweep, credit/rep side-effects, all errors
- bounty_pillar: Single release required, apply/withdraw/submit gate,
  credit charge and 50% refund, select_winners pay+profile, all errors
- hackathon_pillar: Single+deadline required, open submit model,
  multi-recipient distribution, cancel refund, all errors

profile:
- credits: bootstrap, spend/earn/refund/admin_grant, all error variants
- reputation: bump/slash/admin_slash, saturation, all error variants
- earnings: register, zero/negative guard, multi-user/token tracking,
  i128::MAX saturation, op replay guard

203 tests passing (146 events + 57 profile). Snapshots regenerated.

Closes boundlessfi#25
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Josue19-08, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 38 minutes and 44 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 82b333ed-60e9-4f5e-9fdb-7a25eb765849

📥 Commits

Reviewing files that changed from the base of the PR and between 9856ab4 and eb378fc.

📒 Files selected for processing (7)
  • contracts/events/src/tests/bounty_pillar.rs
  • contracts/events/src/tests/cancel_refund.rs
  • contracts/events/src/tests/escrow_fee_math.rs
  • contracts/events/src/tests/grant_pillar.rs
  • contracts/events/src/tests/hackathon_pillar.rs
  • contracts/events/src/tests/token_whitelist.rs
  • contracts/profile/src/tests/earnings.rs
📝 Walkthrough

Walkthrough

The PR rewrites and adds test modules for events and profile contract coverage. It adds new event tests for token whitelist, cancel refunds, fee math, and grant behavior, and streamlines bounty and hackathon test coverage. It also adds profile earnings and reputation tests and trims credits coverage.

Changes

Events contract tests

Layer / File(s) Summary
Module wiring and token whitelist
contracts/events/src/tests/mod.rs, contracts/events/src/tests/token_whitelist.rs
tests/mod.rs registers the new event test areas, and token_whitelist.rs covers supported-token registration, deregistration, and create-event rejection for unsupported or removed tokens.
Fee math and winner release
contracts/events/src/tests/escrow_fee_math.rs
escrow_fee_math.rs adds fee-bps setup, override and waiver coverage, invalid override rejection, winner release math, and admin fee updates.
Cancel refund batches
contracts/events/src/tests/cancel_refund.rs
cancel_refund.rs adds inline settlement, paged batch processing, partner and owner payouts, pro-rata boundary behavior, and cancel lifecycle error checks.
Bounty pillar coverage
contracts/events/src/tests/bounty_pillar.rs
bounty_pillar.rs narrows create validation, application and withdrawal flows, submission gating, winner selection, and cancel end-state checks.
Hackathon pillar coverage
contracts/events/src/tests/hackathon_pillar.rs
hackathon_pillar.rs keeps create validation, submit and withdraw behavior, winner selection, and cancel assertions while removing broader edge-case checks.
Grant milestone claims
contracts/events/src/tests/grant_pillar.rs
grant_pillar.rs covers multi-release creation, milestone claim math, claim side effects, replay and bounds errors, and multi-winner completion.

Profile contract tests

Layer / File(s) Summary
Module wiring and credits coverage
contracts/profile/src/tests/mod.rs, contracts/profile/src/tests/credits.rs
tests/mod.rs registers the new profile submodules, and credits.rs keeps streamlined bootstrap, spend, earn, refund, and admin-grant checks.
Earnings tracking
contracts/profile/src/tests/earnings.rs
earnings.rs covers accumulation, amount validation, per-key isolation, saturation, replay protection, unknown-key defaults, and auth-related registration.
Reputation operations
contracts/profile/src/tests/reputation.rs
reputation.rs covers bump, slash, and admin-slash behavior with missing-profile, replay, empty-reason, admin-auth, and saturation checks.

Estimated review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

  • boundlessfi/boundless-contract issue 26 — credits.rs rewrites the credits coverage around bootstrap, spend, earn, refund, and admin-grant flows.
  • boundlessfi/boundless-contract issue 27 — token_whitelist.rs adds supported-token registration, deregistration, and event creation gating.
  • boundlessfi/boundless-contract issue 28 — cancel_refund.rs adds cancel pagination, refund ordering, and lifecycle error coverage.
  • boundlessfi/boundless-contract issue 29 — reputation.rs adds bump, slash, and admin-slash coverage with replay and auth checks.
  • boundlessfi/boundless-contract issue 31 — escrow_fee_math.rs adds fee override, waiver, and release-math cases.
  • boundlessfi/boundless-contract issue 32 — grant_pillar.rs adds multi-release grant creation and milestone-claim math.
  • boundlessfi/boundless-contract issue 33 — bounty_pillar.rs keeps apply and withdraw credit-flow coverage plus winner selection checks.

Possibly related PRs

Poem

A bunny hopped through tests at dawn,
With carrots, credits, and fees in paw.
Whitelist gates and winner glows,
Grant and bounty, the garden grows.
Hop hop—clean hops all the way! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: adding nine contract test modules for coverage.
Linked Issues check ✅ Passed The PR adds the listed events/profile test modules and covers the issue's coverage matrix across all nine subareas.
Out of Scope Changes check ✅ Passed All changes are confined to test coverage modules and test registration, with no unrelated scope creep evident.
Docstring Coverage ✅ Passed Docstring coverage is 83.21% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (1)
contracts/events/src/tests/cancel_refund.rs (1)

207-277: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Misleading name/header and dead scratch comments in this test.

This test actually exercises the ProRataPartners branch, not a boundary case:

  • The section header (Lines 207-209) says boundary: remaining == non_owner_total, but the realized state is remaining = 800 < non_owner_total = 1000, i.e. strict pro-rata.
  • The name cancel_at_boundary_pays_partners_full_no_owner_residual is inaccurate — partners receive the pro-rated 400 each (Lines 274-275), not their full 500 contribution.
  • Lines 213-214 and 240-255 are a large block of contradictory, self-correcting scratch reasoning that doesn't describe the final test and should be removed.

Rename to reflect the ProRata path and replace the scratch block with a single accurate comment of the realized math.

♻️ Suggested cleanup
-// ============================================================
-// ProRataPartners branch (boundary: remaining == non_owner_total)
-// ============================================================
-
-#[test]
-fn cancel_at_boundary_pays_partners_full_no_owner_residual() {
-    // 60/40 split; pay position 1 (60%); remaining = 40% of escrow.
-    // With partner pool == remaining, no owner residual.
+// ============================================================
+// ProRataPartners branch (remaining < non_owner_total)
+// ============================================================
+
+#[test]
+fn cancel_prorata_splits_remaining_across_partners_no_owner_residual() {
+    // escrow = 2000 (owner 1000 + p1 500 + p2 500); select_winners pays
+    // pos1 60% (1200) leaving remaining = 800. non_owner_total = 1000.
+    // 800 < 1000 -> ProRata: each partner gets 500 * 800 / 1000 = 400; owner = 0.

Also drop the stale reasoning block at Lines 240-255.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@contracts/events/src/tests/cancel_refund.rs` around lines 207 - 277, This
test is mislabeled and contains stale scratch reasoning: the scenario in
cancel_at_boundary_pays_partners_full_no_owner_residual actually exercises the
ProRataPartners path, not the boundary/full-partner case. Rename the test and
header to reflect the realized math in drive_cancel and
ctx.events.select_winners, and replace the contradictory comment block with one
short accurate explanation of the final state (remaining < non_owner_total, so
each partner gets a pro-rated share and owner gets nothing). Remove the dead
self-correcting comments so the test only documents the final intended behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@contracts/events/src/tests/bounty_pillar.rs`:
- Around line 244-267: The single-recipient payout test in
select_winners_pays_recipient_and_updates_profile only checks the applicant’s
balance change and misses the required fee-account balance delta assertion.
Update this test to also verify the fee_account balance change after
ctx.events.select_winners, using the existing Ctx.fee_account and the token
client, so the payout split path covers both recipient and fee balances as
required.

In `@contracts/events/src/tests/cancel_refund.rs`:
- Around line 132-153: The refund/sweep payout tests currently assert only
recipient and owner balance deltas, but they do not verify that the fee account
remains unchanged, so a fee-skimming regression would be missed. Update the
payout-affecting tests in cancel_refund.rs, especially
full_partner_then_residual_pays_partners_and_owner,
paged_cancel_processes_in_batches, and the cancel_at_boundary_* cases, to
capture the fee account balance from Ctx before and after drive_cancel and
assert its delta is zero alongside the existing balance checks.

In `@contracts/events/src/tests/escrow_fee_math.rs`:
- Around line 199-217: Update the payout-path tests in escrow_fee_math.rs to
assert fee-account balance deltas alongside recipient balances. In
select_winners_single_100_percent_drains_escrow and the other payout split tests
referenced by the review, capture the fee account balance before and after
calling Events::select_winners and verify it does not change for these hackathon
winner-release paths, while still checking the recipient payout and
remaining_escrow/status outcomes. Use the existing setup(), token::Client, and
ctx.events.select_winners flows so the assertions cover both the
single-position, multi-position, and sweep cases consistently.

In `@contracts/events/src/tests/grant_pillar.rs`:
- Around line 154-169: The payout-split tests are missing assertions for the
fee-account balance delta even though they already verify recipient deltas.
Update the grant_pillar tests in the
claim_milestone_pays_fixed_per_milestone_amount,
claim_milestone_last_sweeps_rounding_residue, and
two_winner_grant_each_claims_their_share paths to also read ctx.fee_account via
token::Client and assert the fee balance change for each split case. Keep the
existing recipient and escrow assertions, and make sure every single-position,
multi-position, and sweep payout test covers both recipient and fee-account
balance changes.

In `@contracts/events/src/tests/hackathon_pillar.rs`:
- Around line 199-220: Add fee-account balance assertions to the payout tests
that currently only verify recipient balances. In the test function
select_winners_single_pays_full_budget_and_updates_profile, and in the
multi-recipient test mentioned in the review, check the fee_account balance
delta alongside the recipient delta after select_winners so the deposit fee
collection is covered. Use the existing setup helpers and identifiers like
ctx.events.select_winners, ctx.fee_account, and token::Client::new to locate the
payout assertions, and make the same coverage consistent with the sweep-path
test.

In `@contracts/events/src/tests/token_whitelist.rs`:
- Around line 117-136: The unsupported-token test only checks that create_event
fails, which is too weak. Update the assertions in
create_event_with_unsupported_token_reverts and the other try_create_event test
to match the specific Error::TokenNotSupported result instead of using is_err().
Use the existing try_create_event call and assert against the exact rejection
reason so the token whitelist behavior is enforced precisely.
- Around line 24-27: Add negative auth tests for the admin-gated whitelist
mutation paths in token_whitelist.rs, because setup() uses env.mock_all_auths()
and only verifies auth requests. Update the existing register/deregister test
cases and add explicit unauthorized-call checks around the whitelist mutation
entry points so non-admin callers are asserted to fail, using the relevant test
helpers and mutation methods in this module. Focus on proving rejection behavior
for both registration and deregistration rather than only successful admin
flows.

In `@contracts/profile/src/tests/earnings.rs`:
- Around line 139-152: The test register_earnings_requires_events_contract_auth
currently only verifies the success path under mock_all_auths and does not
assert the unauthorized failure it claims to cover. Update the earnings test in
register_earnings_requires_events_contract_auth to include a
try_register_earnings call that is rejected when the caller is not the
configured events contract, and assert that the auth check fails before the
state update; if you intend to keep only the success case, rename the test to
match its actual behavior.

---

Nitpick comments:
In `@contracts/events/src/tests/cancel_refund.rs`:
- Around line 207-277: This test is mislabeled and contains stale scratch
reasoning: the scenario in
cancel_at_boundary_pays_partners_full_no_owner_residual actually exercises the
ProRataPartners path, not the boundary/full-partner case. Rename the test and
header to reflect the realized math in drive_cancel and
ctx.events.select_winners, and replace the contradictory comment block with one
short accurate explanation of the final state (remaining < non_owner_total, so
each partner gets a pro-rated share and owner gets nothing). Remove the dead
self-correcting comments so the test only documents the final intended behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7e26aeca-6dbd-4fd3-904a-54286b7092f6

📥 Commits

Reviewing files that changed from the base of the PR and between b80f064 and 9856ab4.

📒 Files selected for processing (11)
  • contracts/events/src/tests/bounty_pillar.rs
  • contracts/events/src/tests/cancel_refund.rs
  • contracts/events/src/tests/escrow_fee_math.rs
  • contracts/events/src/tests/grant_pillar.rs
  • contracts/events/src/tests/hackathon_pillar.rs
  • contracts/events/src/tests/mod.rs
  • contracts/events/src/tests/token_whitelist.rs
  • contracts/profile/src/tests/credits.rs
  • contracts/profile/src/tests/earnings.rs
  • contracts/profile/src/tests/mod.rs
  • contracts/profile/src/tests/reputation.rs

Comment thread contracts/events/src/tests/bounty_pillar.rs
Comment thread contracts/events/src/tests/cancel_refund.rs
Comment thread contracts/events/src/tests/escrow_fee_math.rs
Comment thread contracts/events/src/tests/grant_pillar.rs
Comment thread contracts/events/src/tests/hackathon_pillar.rs
Comment thread contracts/events/src/tests/token_whitelist.rs
Comment thread contracts/events/src/tests/token_whitelist.rs
Comment thread contracts/profile/src/tests/earnings.rs
- Add fee-account balance delta assertions to all payout split paths
  (bounty, hackathon, escrow_fee_math, grant single/sweep/multi-winner)
- Add fee-account delta=0 assertions to cancel refund payout tests
  (full_partner_then_residual, paged_cancel, prorata)
- Rename cancel_at_boundary test to cancel_prorata_splits_remaining;
  remove stale scratch comments, fix section header
- Change is_err() to assert_eq!(err, Error::TokenNotSupported) in
  token whitelist create_event rejection tests
- Add register_without_admin_auth_reverts and
  deregister_without_admin_auth_reverts negative auth tests
- Rename register_earnings_requires_events_contract_auth and add
  register_earnings_without_events_contract_auth_reverts with a real
  impostor-auth rejection check
@Josue19-08

Copy link
Copy Markdown
Author

All CodeRabbit findings addressed in the latest commit (eb378fc):

  • Fee-account delta assertions added to every payout split path: bounty select_winners, hackathon single + multi-recipient, escrow_fee_math single/60-40/top-up sweep, grant single milestone/last-milestone sweep/two-winner multi.
  • Cancel refund tests now assert fee_account delta is 0 after drive_cancel in full_partner_then_residual, paged_cancel_processes_in_batches, and the ProRata test.
  • ProRata test renamed: cancel_at_boundary_pays_partners_full_no_owner_residualcancel_prorata_splits_remaining_across_partners_no_owner_residual; section header updated; stale scratch comments removed.
  • Token whitelist rejection tests: is_err() replaced with assert_eq!(err, Error::TokenNotSupported) for both unsupported and deregistered-token cases.
  • Negative auth tests added: register_without_admin_auth_reverts and deregister_without_admin_auth_reverts verify that calls without admin auth are rejected.
  • Earnings auth test fixed: renamed to register_earnings_succeeds_when_events_contract_is_authorized; new register_earnings_without_events_contract_auth_reverts test uses an impostor address and asserts the call is rejected.

209 tests passing (147 events + 62 profile), zero warnings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Epic: contract test-coverage push (events + profile)

1 participant