Skip to content

Add integration tests for pledge reconcile flow - #456

Merged
ritik4ever merged 2 commits into
ritik4ever:mainfrom
all-opensource-projects:integration-test-for-the-full-pledge-reconcile-flow
Jun 2, 2026
Merged

Add integration tests for pledge reconcile flow#456
ritik4ever merged 2 commits into
ritik4ever:mainfrom
all-opensource-projects:integration-test-for-the-full-pledge-reconcile-flow

Conversation

@meshackyaro

@meshackyaro meshackyaro commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR adds comprehensive integration tests for the complete pledge reconcile flow, covering the full sequence from campaign creation to confirmed pledge in event history.

Changes

  • ✅ Added 5 integration tests covering the pledge reconcile workflow
  • ✅ Test full flow: Create campaign → Pledge → Reconcile → Verify history → Idempotency check
  • ✅ Test edge cases: exceeding target, closed campaigns, duplicate transaction hashes
  • ✅ Test multiple reconciled pledges from different contributors
  • ✅ Fixed mock Stellar addresses to be exactly 56 characters

Test Coverage

  1. Full reconcile flow - Complete workflow with idempotency verification
  2. Funding cap validation - Prevents pledges exceeding campaign target
  3. Campaign state validation - Prevents reconciling to claimed campaigns
  4. Transaction hash uniqueness - Rejects duplicate hashes across campaigns
  5. Multiple pledges - Handles concurrent reconciled pledges correctly

Acceptance Criteria Met

  • ✅ Campaign created via POST /campaigns
  • ✅ Pledge submitted via POST /campaigns/:id/pledges
  • ✅ Reconcile called with a fake transactionHash
  • ✅ GET /campaigns/:id/history confirms the reconcile event
  • ✅ Second reconcile with same hash returns existing pledge (idempotency check)

Test Results

All 5 tests in the "Pledge Reconcile Flow - Integration" suite are passing.

Closes #316

Summary by CodeRabbit

  • Tests
    • Updated integration tests to align payloads and API response shapes for campaign and pledge operations.
    • Adjusted campaign/pledge payload fields and request defaults, including automatic generation of valid transaction hashes when omitted.
    • Added end-to-end pledge reconciliation tests covering successful reconciles, idempotency, funding-limit and closed-campaign rejections, transaction-hash conflict handling, and multi-pledge history/event verification.

@vercel

vercel Bot commented Jun 1, 2026

Copy link
Copy Markdown

@meshackyaro is attempting to deploy a commit to the ritik4ever's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Jun 1, 2026

Copy link
Copy Markdown

@meshackyaro Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0f43db59-2177-4d36-aec0-9b9c5f3864a8

📥 Commits

Reviewing files that changed from the base of the PR and between bc17451 and 2ed94ef.

📒 Files selected for processing (1)
  • backend/tests/integration.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/tests/integration.test.ts

📝 Walkthrough

Walkthrough

Updates backend integration tests: standardized wallet fixtures and tx-hash helper, switched campaign/pledge payload fields to the new schema, changed history assertions to use history.data.data[...], and added a full pledge reconciliation integration test suite exercising reconcile success, edge cases, and history verification.

Changes

Pledge Reconciliation Integration Testing

Layer / File(s) Summary
Test Fixtures, Helpers, and Bootstrap Updates
backend/tests/integration.test.ts
Wallet address constants updated; new generateTxHash() helper producing 64-char hex hashes; campaign creation uses acceptedTokens; pledge creation includes assetCode; claimTestCampaign defaults transactionHash to generateTxHash(); initCampaignStore() imported and called in beforeAll.
History/assertion shape updates
backend/tests/integration.test.ts
All history access and event filtering updated to use history.data.data[...]; ordered-history checks adjusted for event types, actors, timestamps, and amounts.
Pledge Reconcile Flow Integration Test Suite
backend/tests/integration.test.ts
New suite covers reconcile success and metadata verification, idempotency for identical tx hashes, funding-cap enforcement, rejects on closed/claimed campaigns, cross-campaign tx-hash conflict (409 / TRANSACTION_HASH_CONFLICT), and multi-contributor reconcile history and unique-tx-hash assertions.

Sequence Diagram

sequenceDiagram
  participant Test as Integration Test
  participant API as Campaign API
  participant ReconcileSvc as Reconcile Service
  participant Store as Campaign Store
  Test->>API: POST /campaigns (acceptedTokens)
  API->>Store: createCampaign(payload)
  Store-->>API: campaignCreated(id)
  API-->>Test: campaign ID
  Test->>API: POST /campaigns/:id/pledges (assetCode)
  API->>Store: addPledge(payload)
  Store-->>API: pledgeAdded
  API-->>Test: pledge confirmed
  Test->>API: POST /campaigns/:id/pledges/reconcile (transactionHash)
  API->>ReconcileSvc: reconcilePledge(request)
  ReconcileSvc->>Store: verifyAndUpdatePledge(txHash)
  Store-->>ReconcileSvc: updatedPledgeState
  ReconcileSvc-->>API: reconcileResult
  API-->>Test: reconciliation response
  Test->>API: GET /campaigns/:id/history
  API->>Store: getCampaignHistory(id)
  Store-->>API: history (includes reconcile event)
  API-->>Test: history data
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I spin a hash, long and neat,

I hop through tests on nimble feet,
Reconcile clicks, events align,
History shows each pledged design,
Hooray — the suite and headers meet!

🚥 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 Title accurately describes the main change: adding integration tests for the pledge reconcile flow, which matches the changeset.
Linked Issues check ✅ Passed PR implements all acceptance criteria from issue #316: campaign creation, pledge submission, reconcile with fake transactionHash, history verification, and idempotency checks.
Out of Scope Changes check ✅ Passed All changes are scoped to integration testing for pledge reconcile flow; no unrelated or extraneous modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% 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 and usage tips.

@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: 1

🧹 Nitpick comments (1)
backend/tests/integration.test.ts (1)

918-923: ⚡ Quick win

Real 2.5s sleep risks exceeding the default test timeout.

This test sleeps 2500ms in addition to multiple sequential HTTP round-trips (pledge, claim, two detail fetches, reconcile). Against Vitest's default 5s per-test timeout, this is tight and can flake on slower CI. Consider passing an explicit timeout to it(...) (and ideally shrinking the wait).

♻️ Set an explicit timeout
-  it("should prevent reconciling pledge to closed campaign", async () => {
+  it("should prevent reconciling pledge to closed campaign", async () => {
+    // ...
+  }, 15000); // explicit timeout to absorb the 2.5s deadline wait + HTTP latency
🤖 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 `@backend/tests/integration.test.ts` around lines 918 - 923, The real 2.5s
sleep plus several HTTP calls can flake the test; update the test that uses the
2500ms setTimeout (the Promise wait before calling claimTestCampaign with
CREATOR_1) to both shrink the hard sleep (e.g., reduce to a much smaller value
or replace with a short polling loop that checks the campaign deadline) and give
the test an explicit larger timeout by passing a timeout to the it(...) call for
this test; locate the test containing the await new Promise((resolve) =>
setTimeout(resolve, 2500)) and the subsequent claimTestCampaign(campaignId,
CREATOR_1) and modify the test declaration to set an explicit timeout while
reducing/removing the long sleep.
🤖 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 `@backend/tests/integration.test.ts`:
- Around line 781-784: Tests in integration.test.ts inconsistently access the
campaign history payload (some use history.data while other places correctly use
history.data.data per the getCampaignHistory AxiosResponse typing); find all
assertions and usages of getCampaignHistory / variable history and change them
to read the events array as history.data.data (e.g., in assertions, length
checks, and indexing) so every test consistently consumes the { data: any[] }
shape returned by GET /api/campaigns/:id/history.

---

Nitpick comments:
In `@backend/tests/integration.test.ts`:
- Around line 918-923: The real 2.5s sleep plus several HTTP calls can flake the
test; update the test that uses the 2500ms setTimeout (the Promise wait before
calling claimTestCampaign with CREATOR_1) to both shrink the hard sleep (e.g.,
reduce to a much smaller value or replace with a short polling loop that checks
the campaign deadline) and give the test an explicit larger timeout by passing a
timeout to the it(...) call for this test; locate the test containing the await
new Promise((resolve) => setTimeout(resolve, 2500)) and the subsequent
claimTestCampaign(campaignId, CREATOR_1) and modify the test declaration to set
an explicit timeout while reducing/removing the long sleep.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: ad16a369-d2a0-4cad-8b48-f21c9fc8d64a

📥 Commits

Reviewing files that changed from the base of the PR and between f138f01 and 3c13a60.

⛔ Files ignored due to path filters (1)
  • backend/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (1)
  • backend/tests/integration.test.ts

Comment thread backend/tests/integration.test.ts
@ritik4ever

Copy link
Copy Markdown
Owner

@meshackyaro please resolve conflicts

- Implement comprehensive test suite covering full reconcile workflow
- Test: Create campaign → Pledge → Reconcile → Verify history → Idempotency
- Test: Prevent reconciling pledges that exceed campaign target
- Test: Prevent reconciling to closed/claimed campaigns
- Test: Reject duplicate transaction hashes across campaigns
- Test: Handle multiple reconciled pledges from different contributors
- Fix mock Stellar addresses to be exactly 56 characters
- All 5 reconcile flow tests passing

Closes ritik4ever#316
- Change all history.data accesses to history.data.data
- Ensures consistent consumption of { data: any[] } shape from GET /api/campaigns/:id/history
- Fixes inconsistency where some tests used history.data while others correctly used history.data.data
- All reconcile flow tests still passing
@meshackyaro
meshackyaro force-pushed the integration-test-for-the-full-pledge-reconcile-flow branch from bc17451 to 2ed94ef Compare June 2, 2026 16:14
@meshackyaro

Copy link
Copy Markdown
Contributor Author

Conflicts Resolved

I've successfully fetched from upstream, performed a safe rebase, and resolved the conflicts in:

  • backend/package-lock.json - Accepted upstream changes and regenerated lock file
  • backend/tests/integration.test.ts - File was renamed from integration_test.ts to integration.test.ts and conflicts resolved

The branch is now cleanly rebased on upstream/main (commit 977984d) and has been force-pushed to update this PR.

@meshackyaro

Copy link
Copy Markdown
Contributor Author

Conflicts resolved

@ritik4ever
ritik4ever merged commit 7caa6cd into ritik4ever:main Jun 2, 2026
1 of 3 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jun 29, 2026
6 tasks
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.

Add backend integration test for the full pledge-reconcile flow

2 participants