[ 
https://issues.apache.org/jira/browse/FINERACT-2609?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Adam Saghy updated FINERACT-2609:
---------------------------------
    Labels: beginner beginner-friendly feign-migration test-infrastructure  
(was: feign-migration test-infrastructure)

> Migrate integration test helpers from RestAssured to Feign client
> -----------------------------------------------------------------
>
>                 Key: FINERACT-2609
>                 URL: https://issues.apache.org/jira/browse/FINERACT-2609
>             Project: Apache Fineract
>          Issue Type: Improvement
>            Reporter: Krishna Mewara
>            Assignee: Krishna Mewara
>            Priority: Trivial
>              Labels: beginner, beginner-friendly, feign-migration, 
> test-infrastructure
>
> h2. Overview
> Migrate Fineract's integration test infrastructure from raw RestAssured HTTP 
> calls to the
> type-safe Feign client ({{{}fineract-client-feign{}}}). Following the 
> Strangler Fig pattern —
> new Feign helpers coexist alongside legacy RestAssured helpers, tests 
> migrated incrementally.
> No big bang rewrite.
> To close: FINERACT-2454
> h2. Why migrate?
>  * RestAssured tests use raw JSON strings and untyped HTTP — brittle, no 
> compile-time safety
>  * Feign client is type-safe, auto-generated from the OpenAPI spec
>  * Catch API contract drift at compile time, not at runtime in CI
> h2. Current State
> ||Metric||Count||
> |Total helper files in {{common/}}|123|
> |Helpers with RestAssured only (unmigrated)|53|
> |Helpers with both RestAssured + Retrofit (mixed)|18|
> |Helpers already using Retrofit ({{{}Calls.ok{}}})|35|
> |Helpers with NO RestAssured (pure utility)|51|
> |Total test files (excluding {{common/}} and Feign)|312|
> |Test files directly importing RestAssured|197 of 312 (63%)|
> |Existing Feign test files|10|
> |Existing Feign helpers|17|
> |Existing Feign modules|7|
> |Existing wrapper interfaces|4|
> h2. Existing Feign Infrastructure
> These are already merged and in {{{}upstream/develop{}}}. Listed here so the 
> scope of remaining
> work is clear and we don't accidentally duplicate what already exists.
> h3. Base Classes
> ||Class||Role||Replaces||
> |{{FeignIntegrationTest}}|Root base for all Feign tests|{{IntegrationTest}} 
> (Retrofit-based)|
> |{{FeignLoanTestBase}}|Wires all loan helpers, ready for loan test 
> migration|{{BaseLoanIntegrationTest}} (decommission target)|
> h3. Helpers (under {{{}client/feign/helpers/{}}})
> ||Helper||Replaces||Coverage||
> |{{FeignLoanHelper}}|{{LoanTransactionHelper}} (3,250 lines)|~16% — core 
> lifecycle only|
> |{{FeignTransactionHelper}}|Extracted from 
> {{LoanTransactionHelper}}|repayment, chargeOff, reAge, inline COB|
> |{{FeignClientHelper}}|{{ClientHelper}} (1,207 lines)|~6 of ~50 methods|
> |{{FeignAccountHelper}}|{{AccountHelper}}|GL account lookup|
> |{{FeignBusinessDateHelper}}|{{BusinessDateHelper}}|Full functional 
> replacement|
> |{{FeignJournalEntryHelper}}|{{JournalEntryHelper}}|Journal verification|
> |{{FeignOfficeHelper}}|{{OfficeHelper}}|Full functional replacement|
> |{{FeignSchedulerHelper}}|{{SchedulerJobHelper}}|Full functional replacement|
> |{{FeignGlobalConfigurationHelper}}|{{GlobalConfigurationHelper}}|Full 
> functional replacement|
> |{{FeignWorkingCapitalLoanHelper}}|{{WorkingCapitalLoanHelper}}|WC loan ops|
> |{{{}FeignSearchHelper{}}}, {{{}FeignTaxComponentHelper{}}}, 
> {{FeignTaxGroupHelper}}|No legacy equivalent|New capability|
> |{{{}FeignNotificationHelper{}}}, {{{}FeignLoanOriginatorHelper{}}}, 
> {{FeignExternalEventHelper}}|No legacy equivalent|New capability|
> h2. Migration Tiers
> h3. Tier 1 — High-Impact
> ||Helper||Importers||RestAssured %||Feign existence||
> |{{Utils.java}}|309|100%|None — migrate last|
> |{{ClientHelper.java}}|216|~80%|{{FeignClientHelper}} (6 methods — extend in 
> PR 2)|
> |{{BaseLoanIntegrationTest.java}}|121|~95%|{{FeignLoanTestBase}} — exists, 
> decommission after charge coverage added|
> |{{LoanTransactionHelper.java}}|118|~55%|{{FeignLoanHelper}} + 
> {{FeignTransactionHelper}} — extend in PR 4|
> |{{SavingsAccountHelper.java}}|37|~97%|None — greenfield target for PR 1|
> h3. Tier 2 — Medium-Impact
> ||Helper||Importers||Feign Beachhead||
> |{{BusinessDateHelper}}|61|{{FeignBusinessDateHelper}} (done)|
> |{{AccountHelper}}|60|{{FeignAccountHelper}} (done)|
> |{{ChargesHelper}}|55|None — PR 3|
> |{{DelinquencyBucketsHelper}}|36|None — PR 3|
> |{{SchedulerJobHelper}}|35|{{FeignSchedulerHelper}} (done)|
> |{{GlobalConfigurationHelper}}|26|{{FeignGlobalConfigurationHelper}} (done)|
> |{{JournalEntryHelper}}|24|{{FeignJournalEntryHelper}} (done)|
> |{{OfficeHelper}}|19|{{FeignOfficeHelper}} (done)|
> |{{GroupHelper}}|17|None — PR 5|
> h3. Tier 3 — Low-Impact / Niche
> {{BatchHelper}} (7 importers), {{{}FixedDepositAccountHelper{}}}, 
> {{{}RecurringDepositAccountHelper{}}},
> and domain-specific helpers with <10 importers each.
> h3. Foundation Layer
> {{Utils.java}} (309 importers) is the RestAssured gateway that nearly all 
> helpers delegate to.
> {*}Deprecate last{*}, only after all helpers above are migrated. The 
> RA-specific methods
> ({{{}initializeRESTAssured(){}}}, HTTP request wrappers) can be 
> {{@Deprecated}} progressively —
> but {{uniqueRandomStringGenerator()}} and 
> {{loginIntoServerAndGetBase64EncodedAuthenticationKey()}}
> are used widely even in non-RA code, so those stay until their callers are 
> migrated.
> h2. Architecture Pattern
> New {{FeignXxxHelper}} classes live under {{{}client/feign/helpers/{}}}. They:
>  * Take {{FineractFeignClient}} via constructor injection
>  * Use {{ok(() -> ...)}} for API calls (via {{FeignCalls}} utility)
>  * Tests extend {{FeignIntegrationTest}} base class
>  * Share the same model classes ({{{}org.apache.fineract.client.models.*{}}}) 
> as Retrofit
> Legacy and Feign helpers coexist — both {{fineract-client}} (Retrofit) and
> {{fineract-client-feign}} are on the classpath simultaneously. The 
> {{exclude}} in
> {{dependencies.gradle}} prevents duplicate model classes.
> h2. Key Design Decisions
>  # *Separate Feign helper classes* — not dual methods in existing helpers
>  # Both clients share model classes — no conflicts
>  # Thin wrapper interfaces only for APIs with unreadable generated names 
> (e.g. {{create6()}} → {{{}createClient(){}}})
>  # Coexistence over replacement — 197 test files still use RestAssured, 
> helper migration enables but doesn't force test-level migration
> h2. Decommission Plan
> These classes will be retired once their Feign replacement has full method 
> coverage.
> Both old and new coexist until importer counts reach zero.
> ||Class||Importers||Depends On||
> |{{BaseLoanIntegrationTest}}|121|PR 4 (charge management added to 
> {{{}FeignLoanHelper{}}})|
> |{{BaseSavingsIntegrationTest}}|—|PR 1 ({{{}FeignSavingsHelper{}}} + 
> {{{}FeignSavingsTestBase{}}})|
> h2. PR Roadmap
> h3. Core PRs
> ||PR||Scope||Status||
> |PR 1|{{FeignSavingsHelper}} + {{FeignSavingsTestBase}} + first savings 
> test|Done|
> |PR 2|Extend {{FeignClientHelper}} (update, delete, search, status 
> transitions)|Done|
> |PR 3|{{FeignChargesHelper}} + {{FeignDelinquencyHelper}}|Done|
> |PR 4|Extend {{FeignLoanHelper}} — charge management + remaining disbursal 
> methods|Done|
> |PR 5|{{FeignGroupHelper}} + {{FeignCenterHelper}}|Not Started|
> |PR 6|Migrate 5–10 simple test files end-to-end from RestAssured to Feign|Not 
> Started|
> h3. Stretch PRs
> ||PR||Scope||Status||
> |PR S1|Batch migrate {{BaseLoanIntegrationTest}} importers to 
> {{FeignLoanTestBase}} (after PR 4)|In Review|
> |PR S2|{{FeignFixedDepositHelper}} + {{FeignRecurringDepositHelper}}|Not 
> Started|
> |PR S3|{{@Deprecated}} on RestAssured-specific methods in {{Utils.java}}|Not 
> Started|
> h2. Progress Log
> ||Date||PR||Ticket||Notes||
> |2026-06-04|[#5934|https://github.com/apache/fineract/pull/5934]|FINERACT-2626|Added
>  missing `rejectedOnDate` and `withdrawnOnDate` fields to 
> `PostSavingsAccountsAccountIdRequest` in Savings Swagger spec. Prerequisite 
> for #5907 the generated Feign client model was missing these fields, causing 
> the reject command to silently fail.|
> |2026-06-07|[#5907|https://github.com/apache/fineract/pull/5907]|FINERACT-2620|Type-safe
>  Feign-based helpers and integration tests for Savings domain. 10 new files: 
> `FeignSavingsHelper`, `FeignSavingsProductHelper`, 
> `FeignSavingsTransactionHelper`, `FeignSavingsTestBase`, 
> `FeignSavingsLifecycleExtension`, `SavingsRequestBuilders`, 
> `SavingsTestData`, `FeignTestConstants`, and `FeignSavingsLifecycleTest` (8 
> tests). Helpers return full response objects for reusability. Depends on 
> #5934 for correct `rejectedOnDate` support.|
> |2026-06-09|[#5955|https://github.com/apache/fineract/pull/5955]|FINERACT-2632|Added
>  missing fields to `PostClientsRequest` (submittedOnDate), 
> `PostClientsClientIdRequest` (withdrawalDate, withdrawalReasonId, 
> reopenedDate), and `PutClientsClientIdRequest` (firstname, lastname) so the 
> generated Feign client models match what the server actually accepts. 
> Prerequisite for #5954.|
> |2026-06-09|[#5954|https://github.com/apache/fineract/pull/5954]|FINERACT-2631|Extends
>  FeignClientHelper from 4 to 16 methods. Adds `ClientRequestBuilders` and 
> `FeignClientLifecycleTest` covering the full client lifecycle: pending 
> creation, activate, close, reject, reactivate, withdraw, undo-reject, 
> undo-withdraw, update, delete, search, and account retrieval. Depends on 
> #5955.|
> |2026-06-11|[#5978|https://github.com/apache/fineract/pull/5978]|FINERACT-2635|Extends
>  the Feign migration to the Charges and Delinquency domains. New files: 
> `ChargeRequestBuilders` (static typed factories mirroring 
> `ClientRequestBuilders`), `FeignChargesHelper` (14 methods across 
> `ChargesApi` and `ClientChargesApi`), `FeignDelinquencyLifecycleTest` (7 
> ordered E2E tests via native 
> `DelinquencyBucketsHelper`/`DelinquencyRangesHelper`). Fixed Swagger spec gap 
> in `ChargesApiResourceSwagger` — 4 fields missing from `PostChargesRequest` 
> caused silent null sends on PUT. Refactored 3 enricher/report tests to use 
> `chargesHelper.createLoanDisbursementCharge()`. `LoanChargesApi` and loan 
> delinquency actions deferred to PR 4.|
> |2026-06-21|[#5997|https://github.com/apache/fineract/pull/5997]|FINERACT-2640|Extends
>  `FeignLoanHelper` with loan charge management, state transitions, 
> disbursement details, and reschedule methods (PR 4 of the roadmap). 3 files, 
> +284 −9. Added 11 loan charge lifecycle methods (`addLoanCharge`, 
> `getLoanCharges`, `updateLoanCharge`, `deleteLoanCharge`, `waiveLoanCharge`, 
> `payLoanCharge`, `adjustLoanCharge`, etc.), 6 state-transition methods 
> (`closeLoan`, `closeAsRescheduled`, `forecloseLoan`, `assignLoanOfficer`, 
> `unassignLoanOfficer`, `recoverGuarantee`), disbursement detail methods 
> (`addAndDeleteDisbursementDetail`, `getDisbursementDetail`, 
> `updateDisbursementDate`, `modifyAvailableDisbursementAmount`), and 
> reschedule methods via `RescheduleLoansApi`. Extended `LoanRequestBuilders` 
> with static typed factories for all new operations. Updated 
> `FeignLoanTestBase` with delegate methods.|
> |2026-06-26|[#6005|https://github.com/apache/fineract/pull/6005]|FINERACT-2649|Migrates
>  5 Tier 1 loan integration tests from `BaseLoanIntegrationTest` 
> (REST-assured) to `FeignLoanTestBase` (Feign client). 15 files, +927 −229. 
> Migrated tests: `LoanPrepayAmountTest`, 
> `LoanProductWithChargeOffBehaviourTest`, `LoanInterestRateFrequencyTest`, 
> `LoanDueCalculationTest`, `FixedLengthLoanProductIntegrationTest`. 
> Infrastructure additions: `FeignRawHttpHelper` for raw JSON when explicit 
> nulls are needed, `LoanProductTemplates` (3 templates), `LoanTestValidators` 
> (`verifyRepaymentSchedule`, `verifyTransactions`). Extended 
> `FeignLoanTestBase` with builders, installment/transaction wrappers, and 
> utilities from `BaseLoanIntegrationTest`. Bug fixes: 
> `FeignClientHelper.createClient()` uses fixed past activation date matching 
> `ClientHelper.DEFAULT_DATE`; `FeignBusinessDateHelper` date-format overloads; 
> automatic ISO vs human-readable date detection in 
> `runAt()`/`updateBusinessDate()`.|



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to