You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@fineract.apache.org by "DeathGun44 (via GitHub)" <gi...@apache.org> on 2026/06/20 05:51:26 UTC

[PR] FINERACT-2649: Migrate Tier 1 loan integration tests to Feign client [fineract]

DeathGun44 opened a new pull request, #6005:
URL: https://github.com/apache/fineract/pull/6005

   ## Description
   
   Migrates 5 Tier 1 loan integration tests from `BaseLoanIntegrationTest` (REST-assured) to `FeignLoanTestBase` (Feign client).
   
   ### Migrated tests
   
   - `LoanPrepayAmountTest`
   - `LoanProductWithChargeOffBehaviourTest`
   - `LoanInterestRateFrequencyTest`
   - `LoanDueCalculationTest`
   - `FixedLengthLoanProductIntegrationTest`
   
   ### Infrastructure additions
   
   - Added `retrieveLoanProduct` and `updateLoanProduct` (typed) methods to `FeignLoanHelper`
   - Added `updateLoanProduct(Long, String)` raw JSON overload in `FeignLoanTestBase` for explicit null values (the `NON_NULL` ObjectMapper prevents typed null serialization)
   - Added REST-assured `requestSpec`/`responseSpec` to `FeignLoanTestBase` for raw JSON edge cases
   - Added `fixedLengthLoanProduct` template to `LoanProductTemplates`
   - Added payment allocation helpers and loan request builders to `LoanRequestBuilders`
   - Added schedule validation helpers to `LoanTestValidators`
   
   ### Bug fixes
   
   - `FeignClientHelper.createClient()` - use fixed past activation date (`04 March 2011`) matching `ClientHelper.DEFAULT_DATE` instead of real system date
   - `FeignBusinessDateHelper` - date format fixed to use `DATETIME_PATTERN` (`dd MMMM yyyy`)
   
   
   ## Checklist
   
   Please make sure these boxes are checked before submitting your pull request - thanks!
   
   - [ ] Write the commit message as per [our guidelines](https://github.com/apache/fineract/blob/develop/CONTRIBUTING.md#pull-requests)
   - [ ] Acknowledge that we will not review PRs that are not passing the build _("green")_ - it is your responsibility to get a proposed PR to pass the build, not primarily the project's maintainers.
   - [ ] Create/update [unit or integration tests](https://fineract.apache.org/docs/current/#_testing) for verifying the changes made.
   - [ ] Follow our [coding conventions](https://cwiki.apache.org/confluence/display/FINERACT/Coding+Conventions).
   - [ ] Add required Swagger annotation and update API documentation at fineract-provider/src/main/resources/static/legacy-docs/apiLive.htm with details of any API changes
   - [ ] [This PR must not be a "code dump"](https://cwiki.apache.org/confluence/display/FINERACT/Pull+Request+Size+Limit). Large changes can be made in a branch, with assistance. Ask for help on the [developer mailing list](https://fineract.apache.org/#contribute).
   
   Your assigned reviewer(s) will follow our [guidelines for code reviews](https://cwiki.apache.org/confluence/display/FINERACT/Code+Review+Guide).
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@fineract.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] FINERACT-2649: Migrate Tier 1 loan integration tests to Feign client [fineract]

Posted by "DeathGun44 (via GitHub)" <gi...@apache.org>.
DeathGun44 commented on PR #6005:
URL: https://github.com/apache/fineract/pull/6005#issuecomment-4759731620

   @Aman-Mittal Done!
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@fineract.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] FINERACT-2649: Migrate Tier 1 loan integration tests to Feign client [fineract]

Posted by "DeathGun44 (via GitHub)" <gi...@apache.org>.
DeathGun44 commented on PR #6005:
URL: https://github.com/apache/fineract/pull/6005#issuecomment-4780641390

   unrelated test failures
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@fineract.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] FINERACT-2649: Migrate Tier 1 loan integration tests to Feign client [fineract]

Posted by "DeathGun44 (via GitHub)" <gi...@apache.org>.
DeathGun44 commented on code in PR #6005:
URL: https://github.com/apache/fineract/pull/6005#discussion_r3454331763


##########
integration-tests/src/test/java/org/apache/fineract/integrationtests/FixedLengthLoanProductIntegrationTest.java:
##########
@@ -18,107 +18,121 @@
  */
 package org.apache.fineract.integrationtests;
 
+import io.restassured.builder.RequestSpecBuilder;
+import io.restassured.builder.ResponseSpecBuilder;
+import io.restassured.http.ContentType;
+import io.restassured.specification.RequestSpecification;
+import io.restassured.specification.ResponseSpecification;
 import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
 import org.apache.fineract.client.models.GetLoansLoanIdResponse;
 import org.apache.fineract.client.models.PostLoanProductsRequest;
-import org.apache.fineract.client.models.PostLoanProductsResponse;
 import org.apache.fineract.client.models.PostLoansRequest;
-import org.apache.fineract.client.models.PostLoansResponse;
 import org.apache.fineract.client.models.PutLoanProductsProductIdRequest;
 import org.apache.fineract.client.models.PutLoanProductsProductIdResponse;
-import org.apache.fineract.integrationtests.common.ClientHelper;
+import org.apache.fineract.integrationtests.client.feign.FeignLoanTestBase;
+import org.apache.fineract.integrationtests.client.feign.modules.LoanTestData;
+import org.apache.fineract.integrationtests.common.Utils;
 import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
 import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.AdvancedPaymentScheduleTransactionProcessor;
-import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
-import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
-public class FixedLengthLoanProductIntegrationTest extends BaseLoanIntegrationTest {
+public class FixedLengthLoanProductIntegrationTest extends FeignLoanTestBase {
 
     @Test
     public void testCreateReadUpdateReadLoanProductWithFixedLength() {
         // create with 4
         PostLoanProductsRequest loanProductsRequest = fixedLengthLoanProduct(4);
-        PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(loanProductsRequest);
-        Assertions.assertNotNull(loanProduct.getResourceId());
+        Long loanProductId = createLoanProduct(loanProductsRequest);
+        Assertions.assertNotNull(loanProductId);
 
         // read
-        GetLoanProductsProductIdResponse getLoanProductsProductIdResponse = loanProductHelper
-                .retrieveLoanProductById(loanProduct.getResourceId());
+        GetLoanProductsProductIdResponse getLoanProductsProductIdResponse = retrieveLoanProduct(loanProductId);
         Assertions.assertEquals(4, getLoanProductsProductIdResponse.getFixedLength());
 
         // update to 5
         PutLoanProductsProductIdRequest updateRequest = new PutLoanProductsProductIdRequest().fixedLength(5).locale("en");
-        PutLoanProductsProductIdResponse putLoanProductsProductIdResponse = loanProductHelper
-                .updateLoanProductById(loanProduct.getResourceId(), updateRequest);
+        PutLoanProductsProductIdResponse putLoanProductsProductIdResponse = updateLoanProduct(loanProductId, updateRequest);
         Assertions.assertNotNull(putLoanProductsProductIdResponse.getResourceId());
 
         // read again
-        getLoanProductsProductIdResponse = loanProductHelper.retrieveLoanProductById(loanProduct.getResourceId());
+        getLoanProductsProductIdResponse = retrieveLoanProduct(loanProductId);
         Assertions.assertEquals(5, getLoanProductsProductIdResponse.getFixedLength());
 
-        // update to null
-        loanTransactionHelper.updateLoanProduct(putLoanProductsProductIdResponse.getResourceId(), """
+        // update to null (raw JSON required to send explicit null through NON_NULL ObjectMapper)
+        updateLoanProduct(loanProductId, """
                 {
                     "fixedLength": null,
                     "locale": "en"
                 }
                 """);
 
         // read again
-        getLoanProductsProductIdResponse = loanProductHelper.retrieveLoanProductById(loanProduct.getResourceId());
+        getLoanProductsProductIdResponse = retrieveLoanProduct(loanProductId);
         Assertions.assertNull(getLoanProductsProductIdResponse.getFixedLength());
     }
 
     @Test
     public void testLoanApplicationWithFixedLengthInheritedFromLoanProduct() {
         runAt("01 January 2023", () -> {
-            Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+            Long clientId = createClient();
 
-            PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(fixedLengthLoanProduct(4));
-            Assertions.assertNotNull(loanProduct.getResourceId());
+            Long loanProductId = createLoanProduct(fixedLengthLoanProduct(4));
+            Assertions.assertNotNull(loanProductId);
 
-            PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProduct.getResourceId(), "01 January 2023", 1000.0, 4);
+            PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProductId, "01 January 2023", 1000.0, 4);
             applicationRequest = applicationRequest
                     .transactionProcessingStrategyCode(LoanProductTestBuilder.ADVANCED_PAYMENT_ALLOCATION_STRATEGY);
 
-            PostLoansResponse loanResponse = loanTransactionHelper.applyLoan(applicationRequest);
-            Long loanId = loanResponse.getLoanId();
+            Long loanId = applyForLoan(applicationRequest);
 
-            GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
+            GetLoansLoanIdResponse loanDetails = getLoanDetails(loanId);
             Assertions.assertEquals(4, loanDetails.getFixedLength());
         });
     }
 
     @Test
     public void testLoanApplicationWithFixedLengthOverriddenByLoanApplication() {
         runAt("01 January 2023", () -> {
-            Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+            Long clientId = createClient();
 
-            PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(fixedLengthLoanProduct(4));
-            Assertions.assertNotNull(loanProduct.getResourceId());
+            Long loanProductId = createLoanProduct(fixedLengthLoanProduct(4));
+            Assertions.assertNotNull(loanProductId);
 
-            PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProduct.getResourceId(), "01 January 2023", 1000.0, 4);
+            PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProductId, "01 January 2023", 1000.0, 4);
             applicationRequest = applicationRequest.fixedLength(5).repaymentEvery(1).repaymentFrequencyType(2).loanTermFrequencyType(2)
                     .loanTermFrequency(4).transactionProcessingStrategyCode(LoanProductTestBuilder.ADVANCED_PAYMENT_ALLOCATION_STRATEGY);
 
-            PostLoansResponse loanResponse = loanTransactionHelper.applyLoan(applicationRequest);
-            Long loanId = loanResponse.getLoanId();
+            Long loanId = applyForLoan(applicationRequest);
 
-            GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
+            GetLoansLoanIdResponse loanDetails = getLoanDetails(loanId);
             Assertions.assertEquals(5, loanDetails.getFixedLength());
         });
     }
 
     private PostLoanProductsRequest fixedLengthLoanProduct(Integer fixedLength) {
         return createOnePeriod30DaysLongNoInterestPeriodicAccrualProductWithAdvancedPaymentAllocation() //
                 .numberOfRepayments(4).repaymentEvery(1) //
-                .repaymentFrequencyType(RepaymentFrequencyType.MONTHS.longValue()) //
-                .loanScheduleType(LoanScheduleType.PROGRESSIVE.toString()) //
+                .repaymentFrequencyType(LoanTestData.RepaymentFrequencyType.MONTHS.longValue()) //
+                .loanScheduleType("PROGRESSIVE") //
                 .transactionProcessingStrategyCode(AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY) //
-                .loanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL.name()) //
+                .loanScheduleProcessingType("HORIZONTAL") //
                 .interestRatePerPeriod(0.0).fixedLength(fixedLength);
     }
 
+    /**
+     * Updates a loan product using raw JSON. Required here because the global NON_NULL ObjectMapper prevents sending
+     * explicit null values through the typed Feign client.
+     */
+    private void updateLoanProduct(Long productId, String rawJsonBody) {

Review Comment:
   good point. I've replaced the REST-assured workaround with a FeignRawHttpHelper that uses java.net.HttpURLConnection directly and no REST-assured dependency at all now. this helper can also serve as a drop-in replacement for all remaining Utils.performServer* calls as we phase out REST-assured entirely.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@fineract.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] FINERACT-2649: Migrate Tier 1 loan integration tests to Feign client [fineract]

Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #6005:
URL: https://github.com/apache/fineract/pull/6005#discussion_r3450863899


##########
integration-tests/src/test/java/org/apache/fineract/integrationtests/FixedLengthLoanProductIntegrationTest.java:
##########
@@ -18,107 +18,121 @@
  */
 package org.apache.fineract.integrationtests;
 
+import io.restassured.builder.RequestSpecBuilder;
+import io.restassured.builder.ResponseSpecBuilder;
+import io.restassured.http.ContentType;
+import io.restassured.specification.RequestSpecification;
+import io.restassured.specification.ResponseSpecification;
 import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
 import org.apache.fineract.client.models.GetLoansLoanIdResponse;
 import org.apache.fineract.client.models.PostLoanProductsRequest;
-import org.apache.fineract.client.models.PostLoanProductsResponse;
 import org.apache.fineract.client.models.PostLoansRequest;
-import org.apache.fineract.client.models.PostLoansResponse;
 import org.apache.fineract.client.models.PutLoanProductsProductIdRequest;
 import org.apache.fineract.client.models.PutLoanProductsProductIdResponse;
-import org.apache.fineract.integrationtests.common.ClientHelper;
+import org.apache.fineract.integrationtests.client.feign.FeignLoanTestBase;
+import org.apache.fineract.integrationtests.client.feign.modules.LoanTestData;
+import org.apache.fineract.integrationtests.common.Utils;
 import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
 import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.AdvancedPaymentScheduleTransactionProcessor;
-import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
-import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
-public class FixedLengthLoanProductIntegrationTest extends BaseLoanIntegrationTest {
+public class FixedLengthLoanProductIntegrationTest extends FeignLoanTestBase {
 
     @Test
     public void testCreateReadUpdateReadLoanProductWithFixedLength() {
         // create with 4
         PostLoanProductsRequest loanProductsRequest = fixedLengthLoanProduct(4);
-        PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(loanProductsRequest);
-        Assertions.assertNotNull(loanProduct.getResourceId());
+        Long loanProductId = createLoanProduct(loanProductsRequest);
+        Assertions.assertNotNull(loanProductId);
 
         // read
-        GetLoanProductsProductIdResponse getLoanProductsProductIdResponse = loanProductHelper
-                .retrieveLoanProductById(loanProduct.getResourceId());
+        GetLoanProductsProductIdResponse getLoanProductsProductIdResponse = retrieveLoanProduct(loanProductId);
         Assertions.assertEquals(4, getLoanProductsProductIdResponse.getFixedLength());
 
         // update to 5
         PutLoanProductsProductIdRequest updateRequest = new PutLoanProductsProductIdRequest().fixedLength(5).locale("en");
-        PutLoanProductsProductIdResponse putLoanProductsProductIdResponse = loanProductHelper
-                .updateLoanProductById(loanProduct.getResourceId(), updateRequest);
+        PutLoanProductsProductIdResponse putLoanProductsProductIdResponse = updateLoanProduct(loanProductId, updateRequest);
         Assertions.assertNotNull(putLoanProductsProductIdResponse.getResourceId());
 
         // read again
-        getLoanProductsProductIdResponse = loanProductHelper.retrieveLoanProductById(loanProduct.getResourceId());
+        getLoanProductsProductIdResponse = retrieveLoanProduct(loanProductId);
         Assertions.assertEquals(5, getLoanProductsProductIdResponse.getFixedLength());
 
-        // update to null
-        loanTransactionHelper.updateLoanProduct(putLoanProductsProductIdResponse.getResourceId(), """
+        // update to null (raw JSON required to send explicit null through NON_NULL ObjectMapper)
+        updateLoanProduct(loanProductId, """
                 {
                     "fixedLength": null,
                     "locale": "en"
                 }
                 """);
 
         // read again
-        getLoanProductsProductIdResponse = loanProductHelper.retrieveLoanProductById(loanProduct.getResourceId());
+        getLoanProductsProductIdResponse = retrieveLoanProduct(loanProductId);
         Assertions.assertNull(getLoanProductsProductIdResponse.getFixedLength());
     }
 
     @Test
     public void testLoanApplicationWithFixedLengthInheritedFromLoanProduct() {
         runAt("01 January 2023", () -> {
-            Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+            Long clientId = createClient();
 
-            PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(fixedLengthLoanProduct(4));
-            Assertions.assertNotNull(loanProduct.getResourceId());
+            Long loanProductId = createLoanProduct(fixedLengthLoanProduct(4));
+            Assertions.assertNotNull(loanProductId);
 
-            PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProduct.getResourceId(), "01 January 2023", 1000.0, 4);
+            PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProductId, "01 January 2023", 1000.0, 4);
             applicationRequest = applicationRequest
                     .transactionProcessingStrategyCode(LoanProductTestBuilder.ADVANCED_PAYMENT_ALLOCATION_STRATEGY);
 
-            PostLoansResponse loanResponse = loanTransactionHelper.applyLoan(applicationRequest);
-            Long loanId = loanResponse.getLoanId();
+            Long loanId = applyForLoan(applicationRequest);
 
-            GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
+            GetLoansLoanIdResponse loanDetails = getLoanDetails(loanId);
             Assertions.assertEquals(4, loanDetails.getFixedLength());
         });
     }
 
     @Test
     public void testLoanApplicationWithFixedLengthOverriddenByLoanApplication() {
         runAt("01 January 2023", () -> {
-            Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+            Long clientId = createClient();
 
-            PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(fixedLengthLoanProduct(4));
-            Assertions.assertNotNull(loanProduct.getResourceId());
+            Long loanProductId = createLoanProduct(fixedLengthLoanProduct(4));
+            Assertions.assertNotNull(loanProductId);
 
-            PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProduct.getResourceId(), "01 January 2023", 1000.0, 4);
+            PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProductId, "01 January 2023", 1000.0, 4);
             applicationRequest = applicationRequest.fixedLength(5).repaymentEvery(1).repaymentFrequencyType(2).loanTermFrequencyType(2)
                     .loanTermFrequency(4).transactionProcessingStrategyCode(LoanProductTestBuilder.ADVANCED_PAYMENT_ALLOCATION_STRATEGY);
 
-            PostLoansResponse loanResponse = loanTransactionHelper.applyLoan(applicationRequest);
-            Long loanId = loanResponse.getLoanId();
+            Long loanId = applyForLoan(applicationRequest);
 
-            GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
+            GetLoansLoanIdResponse loanDetails = getLoanDetails(loanId);
             Assertions.assertEquals(5, loanDetails.getFixedLength());
         });
     }
 
     private PostLoanProductsRequest fixedLengthLoanProduct(Integer fixedLength) {
         return createOnePeriod30DaysLongNoInterestPeriodicAccrualProductWithAdvancedPaymentAllocation() //
                 .numberOfRepayments(4).repaymentEvery(1) //
-                .repaymentFrequencyType(RepaymentFrequencyType.MONTHS.longValue()) //
-                .loanScheduleType(LoanScheduleType.PROGRESSIVE.toString()) //
+                .repaymentFrequencyType(LoanTestData.RepaymentFrequencyType.MONTHS.longValue()) //
+                .loanScheduleType("PROGRESSIVE") //
                 .transactionProcessingStrategyCode(AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY) //
-                .loanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL.name()) //
+                .loanScheduleProcessingType("HORIZONTAL") //
                 .interestRatePerPeriod(0.0).fixedLength(fixedLength);
     }
 
+    /**
+     * Updates a loan product using raw JSON. Required here because the global NON_NULL ObjectMapper prevents sending
+     * explicit null values through the typed Feign client.
+     */
+    private void updateLoanProduct(Long productId, String rawJsonBody) {

Review Comment:
   Our plan is to completely remove RestAssured at some point in the future. I was wondering if we should instead create a fineract client with an object mapper that allows null values to be sent for this test instead? Can you look into whether we can do this?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@fineract.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] FINERACT-2649: Migrate Tier 1 loan integration tests to Feign client [fineract]

Posted by "budaidev (via GitHub)" <gi...@apache.org>.
budaidev commented on code in PR #6005:
URL: https://github.com/apache/fineract/pull/6005#discussion_r3448376279


##########
integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/FeignLoanTestBase.java:
##########
@@ -120,6 +153,23 @@ protected Long createLoanProduct(PostLoanProductsRequest request) {
         return loanHelper.createLoanProduct(request);
     }
 
+    protected GetLoanProductsProductIdResponse retrieveLoanProduct(Long productId) {
+        return loanHelper.retrieveLoanProduct(productId);
+    }
+
+    protected PutLoanProductsProductIdResponse updateLoanProduct(Long productId, PutLoanProductsProductIdRequest request) {
+        return loanHelper.updateLoanProduct(productId, request);
+    }
+
+    /**
+     * Updates a loan product using raw JSON. Use this overload when you need to send explicit null values in the
+     * request body, which the typed Feign client cannot express due to the global NON_NULL ObjectMapper configuration.
+     */
+    protected void updateLoanProduct(Long productId, String rawJsonBody) {

Review Comment:
   I understand this is a workaround, but this change will force to load restassured on every subclass, which is not ideal. Can we separate this 



##########
integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/helpers/FeignClientHelper.java:
##########
@@ -57,7 +57,7 @@ public FeignClientHelper(FineractFeignClient fineractClient) {
     }
 
     public Long createClient() {
-        return createClient(Utils.dateFormatter.format(Utils.getLocalDateOfTenant()));
+        return createClient("04 March 2011");

Review Comment:
   Magic string



##########
integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/FeignLoanTestBase.java:
##########
@@ -337,4 +403,338 @@ protected PostLoansLoanIdTransactionsRequest reAge(String startDate, String freq
             Integer numberOfInstallments) {
         return LoanRequestBuilders.reAge(startDate, frequencyType, frequencyNumber, numberOfInstallments);
     }
+
+    protected LoanTestData.TransactionExt transaction(double amount, String type, String date, double outstandingPrincipal,
+            double principalPortion, double interestPortion, double feePortion, double penaltyPortion, double unrecognizedIncomePortion,
+            double overpaymentPortion) {
+        return new LoanTestData.TransactionExt(amount, type, date, outstandingPrincipal, principalPortion, interestPortion, feePortion,
+                penaltyPortion, unrecognizedIncomePortion, overpaymentPortion, false);
+    }
+
+    protected LoanTestData.TransactionExt transaction(double amount, String type, String date, double outstandingPrincipal,
+            double principalPortion, double interestPortion, double feePortion, double penaltyPortion, double unrecognizedIncomePortion,
+            double overpaymentPortion, boolean reversed) {
+        return new LoanTestData.TransactionExt(amount, type, date, outstandingPrincipal, principalPortion, interestPortion, feePortion,
+                penaltyPortion, unrecognizedIncomePortion, overpaymentPortion, reversed);
+    }
+
+    protected LoanTestData.Installment installment(double principalAmount, Boolean completed, String dueDate) {
+        return new LoanTestData.Installment(principalAmount, null, null, null, null, completed, dueDate, null, null);
+    }
+
+    protected LoanTestData.Installment installment(double principalAmount, double interestAmount, double totalOutstandingAmount,
+            Boolean completed, String dueDate) {
+        return new LoanTestData.Installment(principalAmount, interestAmount, null, null, totalOutstandingAmount, completed, dueDate, null,
+                null);
+    }
+
+    protected LoanTestData.Installment installment(double principalAmount, double interestAmount, double feeAmount,
+            double totalOutstandingAmount, Boolean completed, String dueDate) {
+        return new LoanTestData.Installment(principalAmount, interestAmount, feeAmount, null, totalOutstandingAmount, completed, dueDate,
+                null, null);
+    }
+
+    protected LoanTestData.Installment installment(double principalAmount, double interestAmount, double feeAmount, double penaltyAmount,
+            double totalOutstandingAmount, Boolean completed, String dueDate) {
+        return new LoanTestData.Installment(principalAmount, interestAmount, feeAmount, penaltyAmount, totalOutstandingAmount, completed,
+                dueDate, null, null);
+    }
+
+    protected LoanTestData.Installment installment(double principalAmount, double interestAmount, double feeAmount, double penaltyAmount,
+            LoanTestData.OutstandingAmounts outstandingAmounts, Boolean completed, String dueDate) {
+        return new LoanTestData.Installment(principalAmount, interestAmount, feeAmount, penaltyAmount, null, completed, dueDate,
+                outstandingAmounts, null);
+    }
+
+    protected LoanTestData.Installment installment(double principalAmount, double interestAmount, double feeAmount, double penaltyAmount,
+            double totalOutstanding, Boolean completed, String dueDate, double loanBalance) {
+        return new LoanTestData.Installment(principalAmount, interestAmount, feeAmount, penaltyAmount, totalOutstanding, completed, dueDate,
+                null, loanBalance);
+    }
+
+    protected LoanTestData.OutstandingAmounts outstanding(double principal, double interestOutstanding, double fee, double penalty,
+            double total) {
+        return new LoanTestData.OutstandingAmounts(principal, interestOutstanding, fee, penalty, total);
+    }
+
+    protected LoanTestData.TransactionExt reversedTransaction(double principalAmount, String type, String date) {
+        return new LoanTestData.TransactionExt(principalAmount, type, date, null, null, null, null, null, null, null, true);
+    }
+
+    protected LoanTestData.TransactionExt transaction(double amount, String type, String date) {
+        return new LoanTestData.TransactionExt(amount, type, date, null, null, null, null, null, null, null, false);
+    }
+
+    protected void verifyTransactions(Long loanId, LoanTestData.TransactionExt... transactions) {
+        GetLoansLoanIdResponse loanDetails = getLoanDetails(loanId);
+        LoanTestValidators.verifyTransactions(loanDetails, transactions);
+    }
+
+    protected void verifyRepaymentSchedule(Long loanId, LoanTestData.Installment... installments) {
+        GetLoansLoanIdResponse loanDetails = getLoanDetails(loanId);
+        LoanTestValidators.verifyRepaymentSchedule(loanDetails, installments);
+    }
+
+    protected PostLoanProductsRequest create4IProgressive() {

Review Comment:
   Can we consolidate this kind of product creation into the LoanProductTemplates? I think this belongs there



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@fineract.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] FINERACT-2649: Migrate Tier 1 loan integration tests to Feign client [fineract]

Posted by "DeathGun44 (via GitHub)" <gi...@apache.org>.
DeathGun44 commented on code in PR #6005:
URL: https://github.com/apache/fineract/pull/6005#discussion_r3454331763


##########
integration-tests/src/test/java/org/apache/fineract/integrationtests/FixedLengthLoanProductIntegrationTest.java:
##########
@@ -18,107 +18,121 @@
  */
 package org.apache.fineract.integrationtests;
 
+import io.restassured.builder.RequestSpecBuilder;
+import io.restassured.builder.ResponseSpecBuilder;
+import io.restassured.http.ContentType;
+import io.restassured.specification.RequestSpecification;
+import io.restassured.specification.ResponseSpecification;
 import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
 import org.apache.fineract.client.models.GetLoansLoanIdResponse;
 import org.apache.fineract.client.models.PostLoanProductsRequest;
-import org.apache.fineract.client.models.PostLoanProductsResponse;
 import org.apache.fineract.client.models.PostLoansRequest;
-import org.apache.fineract.client.models.PostLoansResponse;
 import org.apache.fineract.client.models.PutLoanProductsProductIdRequest;
 import org.apache.fineract.client.models.PutLoanProductsProductIdResponse;
-import org.apache.fineract.integrationtests.common.ClientHelper;
+import org.apache.fineract.integrationtests.client.feign.FeignLoanTestBase;
+import org.apache.fineract.integrationtests.client.feign.modules.LoanTestData;
+import org.apache.fineract.integrationtests.common.Utils;
 import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
 import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.AdvancedPaymentScheduleTransactionProcessor;
-import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
-import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
-public class FixedLengthLoanProductIntegrationTest extends BaseLoanIntegrationTest {
+public class FixedLengthLoanProductIntegrationTest extends FeignLoanTestBase {
 
     @Test
     public void testCreateReadUpdateReadLoanProductWithFixedLength() {
         // create with 4
         PostLoanProductsRequest loanProductsRequest = fixedLengthLoanProduct(4);
-        PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(loanProductsRequest);
-        Assertions.assertNotNull(loanProduct.getResourceId());
+        Long loanProductId = createLoanProduct(loanProductsRequest);
+        Assertions.assertNotNull(loanProductId);
 
         // read
-        GetLoanProductsProductIdResponse getLoanProductsProductIdResponse = loanProductHelper
-                .retrieveLoanProductById(loanProduct.getResourceId());
+        GetLoanProductsProductIdResponse getLoanProductsProductIdResponse = retrieveLoanProduct(loanProductId);
         Assertions.assertEquals(4, getLoanProductsProductIdResponse.getFixedLength());
 
         // update to 5
         PutLoanProductsProductIdRequest updateRequest = new PutLoanProductsProductIdRequest().fixedLength(5).locale("en");
-        PutLoanProductsProductIdResponse putLoanProductsProductIdResponse = loanProductHelper
-                .updateLoanProductById(loanProduct.getResourceId(), updateRequest);
+        PutLoanProductsProductIdResponse putLoanProductsProductIdResponse = updateLoanProduct(loanProductId, updateRequest);
         Assertions.assertNotNull(putLoanProductsProductIdResponse.getResourceId());
 
         // read again
-        getLoanProductsProductIdResponse = loanProductHelper.retrieveLoanProductById(loanProduct.getResourceId());
+        getLoanProductsProductIdResponse = retrieveLoanProduct(loanProductId);
         Assertions.assertEquals(5, getLoanProductsProductIdResponse.getFixedLength());
 
-        // update to null
-        loanTransactionHelper.updateLoanProduct(putLoanProductsProductIdResponse.getResourceId(), """
+        // update to null (raw JSON required to send explicit null through NON_NULL ObjectMapper)
+        updateLoanProduct(loanProductId, """
                 {
                     "fixedLength": null,
                     "locale": "en"
                 }
                 """);
 
         // read again
-        getLoanProductsProductIdResponse = loanProductHelper.retrieveLoanProductById(loanProduct.getResourceId());
+        getLoanProductsProductIdResponse = retrieveLoanProduct(loanProductId);
         Assertions.assertNull(getLoanProductsProductIdResponse.getFixedLength());
     }
 
     @Test
     public void testLoanApplicationWithFixedLengthInheritedFromLoanProduct() {
         runAt("01 January 2023", () -> {
-            Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+            Long clientId = createClient();
 
-            PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(fixedLengthLoanProduct(4));
-            Assertions.assertNotNull(loanProduct.getResourceId());
+            Long loanProductId = createLoanProduct(fixedLengthLoanProduct(4));
+            Assertions.assertNotNull(loanProductId);
 
-            PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProduct.getResourceId(), "01 January 2023", 1000.0, 4);
+            PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProductId, "01 January 2023", 1000.0, 4);
             applicationRequest = applicationRequest
                     .transactionProcessingStrategyCode(LoanProductTestBuilder.ADVANCED_PAYMENT_ALLOCATION_STRATEGY);
 
-            PostLoansResponse loanResponse = loanTransactionHelper.applyLoan(applicationRequest);
-            Long loanId = loanResponse.getLoanId();
+            Long loanId = applyForLoan(applicationRequest);
 
-            GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
+            GetLoansLoanIdResponse loanDetails = getLoanDetails(loanId);
             Assertions.assertEquals(4, loanDetails.getFixedLength());
         });
     }
 
     @Test
     public void testLoanApplicationWithFixedLengthOverriddenByLoanApplication() {
         runAt("01 January 2023", () -> {
-            Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+            Long clientId = createClient();
 
-            PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(fixedLengthLoanProduct(4));
-            Assertions.assertNotNull(loanProduct.getResourceId());
+            Long loanProductId = createLoanProduct(fixedLengthLoanProduct(4));
+            Assertions.assertNotNull(loanProductId);
 
-            PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProduct.getResourceId(), "01 January 2023", 1000.0, 4);
+            PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProductId, "01 January 2023", 1000.0, 4);
             applicationRequest = applicationRequest.fixedLength(5).repaymentEvery(1).repaymentFrequencyType(2).loanTermFrequencyType(2)
                     .loanTermFrequency(4).transactionProcessingStrategyCode(LoanProductTestBuilder.ADVANCED_PAYMENT_ALLOCATION_STRATEGY);
 
-            PostLoansResponse loanResponse = loanTransactionHelper.applyLoan(applicationRequest);
-            Long loanId = loanResponse.getLoanId();
+            Long loanId = applyForLoan(applicationRequest);
 
-            GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
+            GetLoansLoanIdResponse loanDetails = getLoanDetails(loanId);
             Assertions.assertEquals(5, loanDetails.getFixedLength());
         });
     }
 
     private PostLoanProductsRequest fixedLengthLoanProduct(Integer fixedLength) {
         return createOnePeriod30DaysLongNoInterestPeriodicAccrualProductWithAdvancedPaymentAllocation() //
                 .numberOfRepayments(4).repaymentEvery(1) //
-                .repaymentFrequencyType(RepaymentFrequencyType.MONTHS.longValue()) //
-                .loanScheduleType(LoanScheduleType.PROGRESSIVE.toString()) //
+                .repaymentFrequencyType(LoanTestData.RepaymentFrequencyType.MONTHS.longValue()) //
+                .loanScheduleType("PROGRESSIVE") //
                 .transactionProcessingStrategyCode(AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY) //
-                .loanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL.name()) //
+                .loanScheduleProcessingType("HORIZONTAL") //
                 .interestRatePerPeriod(0.0).fixedLength(fixedLength);
     }
 
+    /**
+     * Updates a loan product using raw JSON. Required here because the global NON_NULL ObjectMapper prevents sending
+     * explicit null values through the typed Feign client.
+     */
+    private void updateLoanProduct(Long productId, String rawJsonBody) {

Review Comment:
   good point. I'll open a separate PR with a Feign-native raw HTTP helper that reuses the existing OkHttp client and auth config. this will replace the REST-assured workaround here and can serve as the drop-in replacement for all remaining Utils.performServer* calls as we phase out REST-assured entirely.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@fineract.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] FINERACT-2649: Migrate Tier 1 loan integration tests to Feign client [fineract]

Posted by "DeathGun44 (via GitHub)" <gi...@apache.org>.
DeathGun44 commented on PR #6005:
URL: https://github.com/apache/fineract/pull/6005#issuecomment-4771367718

   Updated the pr description with the changes


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@fineract.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] FINERACT-2649: Migrate Tier 1 loan integration tests to Feign client [fineract]

Posted by "DeathGun44 (via GitHub)" <gi...@apache.org>.
DeathGun44 commented on code in PR #6005:
URL: https://github.com/apache/fineract/pull/6005#discussion_r3448746544


##########
integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/FeignLoanTestBase.java:
##########
@@ -120,6 +153,23 @@ protected Long createLoanProduct(PostLoanProductsRequest request) {
         return loanHelper.createLoanProduct(request);
     }
 
+    protected GetLoanProductsProductIdResponse retrieveLoanProduct(Long productId) {
+        return loanHelper.retrieveLoanProduct(productId);
+    }
+
+    protected PutLoanProductsProductIdResponse updateLoanProduct(Long productId, PutLoanProductsProductIdRequest request) {
+        return loanHelper.updateLoanProduct(productId, request);
+    }
+
+    /**
+     * Updates a loan product using raw JSON. Use this overload when you need to send explicit null values in the
+     * request body, which the typed Feign client cannot express due to the global NON_NULL ObjectMapper configuration.
+     */
+    protected void updateLoanProduct(Long productId, String rawJsonBody) {

Review Comment:
   Done! It's now a private method in FixedLengthLoanProductIntegrationTest.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@fineract.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] FINERACT-2649: Migrate Tier 1 loan integration tests to Feign client [fineract]

Posted by "DeathGun44 (via GitHub)" <gi...@apache.org>.
DeathGun44 commented on code in PR #6005:
URL: https://github.com/apache/fineract/pull/6005#discussion_r3448747515


##########
integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/helpers/FeignClientHelper.java:
##########
@@ -57,7 +57,7 @@ public FeignClientHelper(FineractFeignClient fineractClient) {
     }
 
     public Long createClient() {
-        return createClient(Utils.dateFormatter.format(Utils.getLocalDateOfTenant()));
+        return createClient("04 March 2011");

Review Comment:
   thank you ,its now fixed!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@fineract.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] FINERACT-2649: Migrate Tier 1 loan integration tests to Feign client [fineract]

Posted by "DeathGun44 (via GitHub)" <gi...@apache.org>.
DeathGun44 commented on PR #6005:
URL: https://github.com/apache/fineract/pull/6005#issuecomment-4801622198

   @budaidev @adamsaghy can you please take a look when you have a moment ,next pr is ready as soon ass this one merges!
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@fineract.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] FINERACT-2649: Migrate Tier 1 loan integration tests to Feign client [fineract]

Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy merged PR #6005:
URL: https://github.com/apache/fineract/pull/6005


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@fineract.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] FINERACT-2649: Migrate Tier 1 loan integration tests to Feign client [fineract]

Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #6005:
URL: https://github.com/apache/fineract/pull/6005#discussion_r3450863899


##########
integration-tests/src/test/java/org/apache/fineract/integrationtests/FixedLengthLoanProductIntegrationTest.java:
##########
@@ -18,107 +18,121 @@
  */
 package org.apache.fineract.integrationtests;
 
+import io.restassured.builder.RequestSpecBuilder;
+import io.restassured.builder.ResponseSpecBuilder;
+import io.restassured.http.ContentType;
+import io.restassured.specification.RequestSpecification;
+import io.restassured.specification.ResponseSpecification;
 import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
 import org.apache.fineract.client.models.GetLoansLoanIdResponse;
 import org.apache.fineract.client.models.PostLoanProductsRequest;
-import org.apache.fineract.client.models.PostLoanProductsResponse;
 import org.apache.fineract.client.models.PostLoansRequest;
-import org.apache.fineract.client.models.PostLoansResponse;
 import org.apache.fineract.client.models.PutLoanProductsProductIdRequest;
 import org.apache.fineract.client.models.PutLoanProductsProductIdResponse;
-import org.apache.fineract.integrationtests.common.ClientHelper;
+import org.apache.fineract.integrationtests.client.feign.FeignLoanTestBase;
+import org.apache.fineract.integrationtests.client.feign.modules.LoanTestData;
+import org.apache.fineract.integrationtests.common.Utils;
 import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
 import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.AdvancedPaymentScheduleTransactionProcessor;
-import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
-import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
-public class FixedLengthLoanProductIntegrationTest extends BaseLoanIntegrationTest {
+public class FixedLengthLoanProductIntegrationTest extends FeignLoanTestBase {
 
     @Test
     public void testCreateReadUpdateReadLoanProductWithFixedLength() {
         // create with 4
         PostLoanProductsRequest loanProductsRequest = fixedLengthLoanProduct(4);
-        PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(loanProductsRequest);
-        Assertions.assertNotNull(loanProduct.getResourceId());
+        Long loanProductId = createLoanProduct(loanProductsRequest);
+        Assertions.assertNotNull(loanProductId);
 
         // read
-        GetLoanProductsProductIdResponse getLoanProductsProductIdResponse = loanProductHelper
-                .retrieveLoanProductById(loanProduct.getResourceId());
+        GetLoanProductsProductIdResponse getLoanProductsProductIdResponse = retrieveLoanProduct(loanProductId);
         Assertions.assertEquals(4, getLoanProductsProductIdResponse.getFixedLength());
 
         // update to 5
         PutLoanProductsProductIdRequest updateRequest = new PutLoanProductsProductIdRequest().fixedLength(5).locale("en");
-        PutLoanProductsProductIdResponse putLoanProductsProductIdResponse = loanProductHelper
-                .updateLoanProductById(loanProduct.getResourceId(), updateRequest);
+        PutLoanProductsProductIdResponse putLoanProductsProductIdResponse = updateLoanProduct(loanProductId, updateRequest);
         Assertions.assertNotNull(putLoanProductsProductIdResponse.getResourceId());
 
         // read again
-        getLoanProductsProductIdResponse = loanProductHelper.retrieveLoanProductById(loanProduct.getResourceId());
+        getLoanProductsProductIdResponse = retrieveLoanProduct(loanProductId);
         Assertions.assertEquals(5, getLoanProductsProductIdResponse.getFixedLength());
 
-        // update to null
-        loanTransactionHelper.updateLoanProduct(putLoanProductsProductIdResponse.getResourceId(), """
+        // update to null (raw JSON required to send explicit null through NON_NULL ObjectMapper)
+        updateLoanProduct(loanProductId, """
                 {
                     "fixedLength": null,
                     "locale": "en"
                 }
                 """);
 
         // read again
-        getLoanProductsProductIdResponse = loanProductHelper.retrieveLoanProductById(loanProduct.getResourceId());
+        getLoanProductsProductIdResponse = retrieveLoanProduct(loanProductId);
         Assertions.assertNull(getLoanProductsProductIdResponse.getFixedLength());
     }
 
     @Test
     public void testLoanApplicationWithFixedLengthInheritedFromLoanProduct() {
         runAt("01 January 2023", () -> {
-            Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+            Long clientId = createClient();
 
-            PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(fixedLengthLoanProduct(4));
-            Assertions.assertNotNull(loanProduct.getResourceId());
+            Long loanProductId = createLoanProduct(fixedLengthLoanProduct(4));
+            Assertions.assertNotNull(loanProductId);
 
-            PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProduct.getResourceId(), "01 January 2023", 1000.0, 4);
+            PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProductId, "01 January 2023", 1000.0, 4);
             applicationRequest = applicationRequest
                     .transactionProcessingStrategyCode(LoanProductTestBuilder.ADVANCED_PAYMENT_ALLOCATION_STRATEGY);
 
-            PostLoansResponse loanResponse = loanTransactionHelper.applyLoan(applicationRequest);
-            Long loanId = loanResponse.getLoanId();
+            Long loanId = applyForLoan(applicationRequest);
 
-            GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
+            GetLoansLoanIdResponse loanDetails = getLoanDetails(loanId);
             Assertions.assertEquals(4, loanDetails.getFixedLength());
         });
     }
 
     @Test
     public void testLoanApplicationWithFixedLengthOverriddenByLoanApplication() {
         runAt("01 January 2023", () -> {
-            Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+            Long clientId = createClient();
 
-            PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(fixedLengthLoanProduct(4));
-            Assertions.assertNotNull(loanProduct.getResourceId());
+            Long loanProductId = createLoanProduct(fixedLengthLoanProduct(4));
+            Assertions.assertNotNull(loanProductId);
 
-            PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProduct.getResourceId(), "01 January 2023", 1000.0, 4);
+            PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProductId, "01 January 2023", 1000.0, 4);
             applicationRequest = applicationRequest.fixedLength(5).repaymentEvery(1).repaymentFrequencyType(2).loanTermFrequencyType(2)
                     .loanTermFrequency(4).transactionProcessingStrategyCode(LoanProductTestBuilder.ADVANCED_PAYMENT_ALLOCATION_STRATEGY);
 
-            PostLoansResponse loanResponse = loanTransactionHelper.applyLoan(applicationRequest);
-            Long loanId = loanResponse.getLoanId();
+            Long loanId = applyForLoan(applicationRequest);
 
-            GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
+            GetLoansLoanIdResponse loanDetails = getLoanDetails(loanId);
             Assertions.assertEquals(5, loanDetails.getFixedLength());
         });
     }
 
     private PostLoanProductsRequest fixedLengthLoanProduct(Integer fixedLength) {
         return createOnePeriod30DaysLongNoInterestPeriodicAccrualProductWithAdvancedPaymentAllocation() //
                 .numberOfRepayments(4).repaymentEvery(1) //
-                .repaymentFrequencyType(RepaymentFrequencyType.MONTHS.longValue()) //
-                .loanScheduleType(LoanScheduleType.PROGRESSIVE.toString()) //
+                .repaymentFrequencyType(LoanTestData.RepaymentFrequencyType.MONTHS.longValue()) //
+                .loanScheduleType("PROGRESSIVE") //
                 .transactionProcessingStrategyCode(AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY) //
-                .loanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL.name()) //
+                .loanScheduleProcessingType("HORIZONTAL") //
                 .interestRatePerPeriod(0.0).fixedLength(fixedLength);
     }
 
+    /**
+     * Updates a loan product using raw JSON. Required here because the global NON_NULL ObjectMapper prevents sending
+     * explicit null values through the typed Feign client.
+     */
+    private void updateLoanProduct(Long productId, String rawJsonBody) {

Review Comment:
   Our plan is to completely remove RestAssured at some point in the future. I was wondering if we should instead create a fineract client with an object mapper that allows null values to be sent for this test instead?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@fineract.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] FINERACT-2649: Migrate Tier 1 loan integration tests to Feign client [fineract]

Posted by "Aman-Mittal (via GitHub)" <gi...@apache.org>.
Aman-Mittal commented on PR #6005:
URL: https://github.com/apache/fineract/pull/6005#issuecomment-4759208110

   @DeathGun44 pls try rebase


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@fineract.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] FINERACT-2649: Migrate Tier 1 loan integration tests to Feign client [fineract]

Posted by "DeathGun44 (via GitHub)" <gi...@apache.org>.
DeathGun44 commented on code in PR #6005:
URL: https://github.com/apache/fineract/pull/6005#discussion_r3448746838


##########
integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/FeignLoanTestBase.java:
##########
@@ -337,4 +403,338 @@ protected PostLoansLoanIdTransactionsRequest reAge(String startDate, String freq
             Integer numberOfInstallments) {
         return LoanRequestBuilders.reAge(startDate, frequencyType, frequencyNumber, numberOfInstallments);
     }
+
+    protected LoanTestData.TransactionExt transaction(double amount, String type, String date, double outstandingPrincipal,
+            double principalPortion, double interestPortion, double feePortion, double penaltyPortion, double unrecognizedIncomePortion,
+            double overpaymentPortion) {
+        return new LoanTestData.TransactionExt(amount, type, date, outstandingPrincipal, principalPortion, interestPortion, feePortion,
+                penaltyPortion, unrecognizedIncomePortion, overpaymentPortion, false);
+    }
+
+    protected LoanTestData.TransactionExt transaction(double amount, String type, String date, double outstandingPrincipal,
+            double principalPortion, double interestPortion, double feePortion, double penaltyPortion, double unrecognizedIncomePortion,
+            double overpaymentPortion, boolean reversed) {
+        return new LoanTestData.TransactionExt(amount, type, date, outstandingPrincipal, principalPortion, interestPortion, feePortion,
+                penaltyPortion, unrecognizedIncomePortion, overpaymentPortion, reversed);
+    }
+
+    protected LoanTestData.Installment installment(double principalAmount, Boolean completed, String dueDate) {
+        return new LoanTestData.Installment(principalAmount, null, null, null, null, completed, dueDate, null, null);
+    }
+
+    protected LoanTestData.Installment installment(double principalAmount, double interestAmount, double totalOutstandingAmount,
+            Boolean completed, String dueDate) {
+        return new LoanTestData.Installment(principalAmount, interestAmount, null, null, totalOutstandingAmount, completed, dueDate, null,
+                null);
+    }
+
+    protected LoanTestData.Installment installment(double principalAmount, double interestAmount, double feeAmount,
+            double totalOutstandingAmount, Boolean completed, String dueDate) {
+        return new LoanTestData.Installment(principalAmount, interestAmount, feeAmount, null, totalOutstandingAmount, completed, dueDate,
+                null, null);
+    }
+
+    protected LoanTestData.Installment installment(double principalAmount, double interestAmount, double feeAmount, double penaltyAmount,
+            double totalOutstandingAmount, Boolean completed, String dueDate) {
+        return new LoanTestData.Installment(principalAmount, interestAmount, feeAmount, penaltyAmount, totalOutstandingAmount, completed,
+                dueDate, null, null);
+    }
+
+    protected LoanTestData.Installment installment(double principalAmount, double interestAmount, double feeAmount, double penaltyAmount,
+            LoanTestData.OutstandingAmounts outstandingAmounts, Boolean completed, String dueDate) {
+        return new LoanTestData.Installment(principalAmount, interestAmount, feeAmount, penaltyAmount, null, completed, dueDate,
+                outstandingAmounts, null);
+    }
+
+    protected LoanTestData.Installment installment(double principalAmount, double interestAmount, double feeAmount, double penaltyAmount,
+            double totalOutstanding, Boolean completed, String dueDate, double loanBalance) {
+        return new LoanTestData.Installment(principalAmount, interestAmount, feeAmount, penaltyAmount, totalOutstanding, completed, dueDate,
+                null, loanBalance);
+    }
+
+    protected LoanTestData.OutstandingAmounts outstanding(double principal, double interestOutstanding, double fee, double penalty,
+            double total) {
+        return new LoanTestData.OutstandingAmounts(principal, interestOutstanding, fee, penalty, total);
+    }
+
+    protected LoanTestData.TransactionExt reversedTransaction(double principalAmount, String type, String date) {
+        return new LoanTestData.TransactionExt(principalAmount, type, date, null, null, null, null, null, null, null, true);
+    }
+
+    protected LoanTestData.TransactionExt transaction(double amount, String type, String date) {
+        return new LoanTestData.TransactionExt(amount, type, date, null, null, null, null, null, null, null, false);
+    }
+
+    protected void verifyTransactions(Long loanId, LoanTestData.TransactionExt... transactions) {
+        GetLoansLoanIdResponse loanDetails = getLoanDetails(loanId);
+        LoanTestValidators.verifyTransactions(loanDetails, transactions);
+    }
+
+    protected void verifyRepaymentSchedule(Long loanId, LoanTestData.Installment... installments) {
+        GetLoansLoanIdResponse loanDetails = getLoanDetails(loanId);
+        LoanTestValidators.verifyRepaymentSchedule(loanDetails, installments);
+    }
+
+    protected PostLoanProductsRequest create4IProgressive() {

Review Comment:
   Done. Moved create4IProgressive() to LoanProductTemplates as a default method.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@fineract.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org