Skip to content

feat(s3): business tests — 7 E2E collection lifecycle flows (STA-130)#144

Merged
Puneethkumarck merged 1 commit into
mainfrom
feature/STA-130-s3-business-tests-v2
Mar 9, 2026
Merged

feat(s3): business tests — 7 E2E collection lifecycle flows (STA-130)#144
Puneethkumarck merged 1 commit into
mainfrom
feature/STA-130-s3-business-tests-v2

Conversation

@Puneethkumarck

@Puneethkumarck Puneethkumarck commented Mar 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add 7 E2E business tests exercising the full collection order lifecycle through real Spring context with TestContainers PostgreSQL + Kafka
  • Tests cover happy path (POST -> webhook -> COLLECTED), collection failure, amount mismatch, refund compensation, idempotency, expiry, and webhook idempotency
  • Uses @Primary PspGateway with predictable pspReferences so webhook tests can match the PSP reference from collection creation

Test plan

  • ./gradlew :fiat-on-ramp:fiat-on-ramp:businessTest — 7 tests pass
  • ./gradlew :fiat-on-ramp:fiat-on-ramp:check — full check (unit + IT + business + JaCoCo) passes
  • CI pipeline passes on PR

Closes STA-130

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests
    • Added comprehensive end-to-end test coverage for collection order lifecycle, including payment processing, refunds, webhook handling, idempotency validation, and expiry scenarios.
    • Established foundational test infrastructure for business-level integration testing.

Add business tests exercising full collection lifecycle through real
Spring context with TestContainers PostgreSQL + Kafka:

- Happy path: POST collection -> Stripe webhook -> COLLECTED + outbox
- Collection failure: webhook with failure -> COLLECTION_FAILED
- Amount mismatch: webhook with wrong amount -> AMOUNT_MISMATCH
- Refund compensation: COLLECTED -> POST refund -> REFUNDED + outbox
- Idempotency: same paymentId -> 200 OK with same collectionId
- Expired collection: past expiresAt -> COLLECTION_FAILED via handler
- Webhook idempotency: duplicate webhook ignored for collected order

Closes STA-130

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Puneethkumarck Puneethkumarck added phase-3 Value Movement MVP service-s3 On-Ramp feature New feature labels Mar 9, 2026
@coderabbitai

coderabbitai Bot commented Mar 9, 2026

Copy link
Copy Markdown

Walkthrough

Adds two new test classes to establish a business test framework for the fiat-on-ramp module: AbstractBusinessTest serves as a semantic base for end-to-end tests running within the full Spring context, while CollectionLifecycleTest provides comprehensive test coverage for collection order lifecycle operations including creation, webhooks, refunds, and idempotency scenarios.

Changes

Cohort / File(s) Summary
Test Framework Base
fiat-on-ramp/src/business-test/java/com/stablecoin/payments/onramp/AbstractBusinessTest.java
New abstract base class extending AbstractIntegrationTest with @Tag("business") annotation for semantic grouping of business-level integration tests.
Collection Lifecycle Business Tests
fiat-on-ramp/src/business-test/java/com/stablecoin/payments/onramp/CollectionLifecycleTest.java
Comprehensive end-to-end test suite covering collection order lifecycle: creation, webhook handling, state transitions (COLLECTION_FAILED, AMOUNT_MISMATCH, REFUNDED), refund flows, idempotency, and expiry scenarios. Includes embedded TestPspConfig with deterministic PSP gateway mock and JDBC-based outbox event verification.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #104: Introduces ComplianceCheckLifecycleTest that extends the newly added AbstractBusinessTest base class for business test organization.
  • PR #138: Adds overlapping end-to-end tests for collection lifecycle and Stripe webhook handling with direct intersection on collection initiation idempotency and PSP ordering semantics.
  • PR #135: Implements CollectionController and CollectionCommandHandler endpoints and collection order lifecycle logic that these business tests exercise.

Suggested labels

test

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the primary change: adding 7 end-to-end business tests for the collection lifecycle, with clear scope (E2E collection flows) and issue reference.
Description check ✅ Passed The description covers the main value proposition (7 E2E tests, full lifecycle coverage, TestContainers setup), test scenarios, and local test results. All critical sections are present and substantive.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/STA-130-s3-business-tests-v2

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@fiat-on-ramp/fiat-on-ramp/src/business-test/java/com/stablecoin/payments/onramp/CollectionLifecycleTest.java`:
- Around line 116-121: The current extractField helper uses fragile string
parsing; replace its implementation to use a JSON parser such as JsonPath or
Jackson to safely extract the field value. Locate the extractField method and
change it to call JsonPath.read(jsonResponse, "$." + fieldName) (or parse with
ObjectMapper.readTree(jsonResponse).get(fieldName).asText()) so extraction
handles nested objects, escaped characters and ordering; ensure you handle
missing fields/nulls consistently and update any tests that rely on the old
behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: d4cbe481-73cf-4775-b7b8-6e10f125126d

📥 Commits

Reviewing files that changed from the base of the PR and between 23fa5f1 and 34c484a.

📒 Files selected for processing (2)
  • fiat-on-ramp/fiat-on-ramp/src/business-test/java/com/stablecoin/payments/onramp/AbstractBusinessTest.java
  • fiat-on-ramp/fiat-on-ramp/src/business-test/java/com/stablecoin/payments/onramp/CollectionLifecycleTest.java

Comment on lines +116 to +121
private static String extractField(String jsonResponse, String fieldName) {
var pattern = "\"" + fieldName + "\":\"";
var start = jsonResponse.indexOf(pattern) + pattern.length();
var end = jsonResponse.indexOf("\"", start);
return jsonResponse.substring(start, end);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider using JsonPath for JSON extraction.

The extractField helper uses naive string parsing that breaks with nested objects, escaped quotes, or field reordering. Since MockMvc already provides JsonPath integration, consider:

JsonPath.read(jsonResponse, "$." + fieldName)

Alternatively, use ObjectMapper.readTree() for type-safe extraction.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@fiat-on-ramp/fiat-on-ramp/src/business-test/java/com/stablecoin/payments/onramp/CollectionLifecycleTest.java`
around lines 116 - 121, The current extractField helper uses fragile string
parsing; replace its implementation to use a JSON parser such as JsonPath or
Jackson to safely extract the field value. Locate the extractField method and
change it to call JsonPath.read(jsonResponse, "$." + fieldName) (or parse with
ObjectMapper.readTree(jsonResponse).get(fieldName).asText()) so extraction
handles nested objects, escaped characters and ordering; ensure you handle
missing fields/nulls consistently and update any tests that rely on the old
behavior.

@Puneethkumarck Puneethkumarck merged commit 3485557 into main Mar 9, 2026
13 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature phase-3 Value Movement MVP service-s3 On-Ramp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant