|
20 | 20 |
|
21 | 21 | import static org.apache.fineract.client.feign.util.FeignCalls.fail; |
22 | 22 | import static org.apache.fineract.client.feign.util.FeignCalls.ok; |
| 23 | +import static org.apache.fineract.test.data.LoanStatus.ACTIVE; |
| 24 | +import static org.apache.fineract.test.data.LoanStatus.APPROVED; |
| 25 | +import static org.apache.fineract.test.data.LoanStatus.SUBMITTED_AND_PENDING_APPROVAL; |
23 | 26 | import static org.assertj.core.api.Assertions.assertThat; |
24 | 27 | import static org.junit.jupiter.api.Assertions.assertNotNull; |
25 | 28 | import static org.junit.jupiter.api.Assertions.assertTrue; |
26 | 29 |
|
27 | 30 | import io.cucumber.datatable.DataTable; |
| 31 | +import io.cucumber.java.en.And; |
28 | 32 | import io.cucumber.java.en.Then; |
29 | 33 | import io.cucumber.java.en.When; |
30 | 34 | import java.math.BigDecimal; |
|
37 | 41 | import org.apache.fineract.client.feign.FineractFeignClient; |
38 | 42 | import org.apache.fineract.client.feign.util.CallFailedRuntimeException; |
39 | 43 | import org.apache.fineract.client.models.DeleteWorkingCapitalLoansLoanIdResponse; |
| 44 | +import org.apache.fineract.client.models.GetDisbursementDetail; |
40 | 45 | import org.apache.fineract.client.models.GetWorkingCapitalLoansLoanIdResponse; |
41 | 46 | import org.apache.fineract.client.models.PostClientsResponse; |
42 | 47 | import org.apache.fineract.client.models.PostWorkingCapitalLoansLoanIdRequest; |
|
45 | 50 | import org.apache.fineract.client.models.PostWorkingCapitalLoansResponse; |
46 | 51 | import org.apache.fineract.client.models.PutWorkingCapitalLoansLoanIdRequest; |
47 | 52 | import org.apache.fineract.client.models.PutWorkingCapitalLoansLoanIdResponse; |
| 53 | +import org.apache.fineract.test.data.LoanStatus; |
48 | 54 | import org.apache.fineract.test.data.workingcapitalproduct.DefaultWorkingCapitalLoanProduct; |
49 | 55 | import org.apache.fineract.test.data.workingcapitalproduct.WorkingCapitalLoanProductResolver; |
50 | 56 | import org.apache.fineract.test.factory.WorkingCapitalLoanRequestFactory; |
| 57 | +import org.apache.fineract.test.helper.ErrorMessageHelper; |
51 | 58 | import org.apache.fineract.test.helper.Utils; |
52 | 59 | import org.apache.fineract.test.messaging.event.EventCheckHelper; |
53 | 60 | import org.apache.fineract.test.stepdef.AbstractStepDef; |
@@ -378,6 +385,23 @@ public void adminAttemptsToModifyNonExistentWorkingCapitalLoan() { |
378 | 385 | log.info("Attempted to modify non-existent working capital loan ID {}", NON_EXISTENT_LOAN_ID); |
379 | 386 | } |
380 | 387 |
|
| 388 | + @Then("Modifying the working capital loan that is Disbursed in Active state results in an error") |
| 389 | + public void modifyingDisbursedWithActiveStateLoanResultsInAnError() { |
| 390 | + final PostWorkingCapitalLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| 391 | + long loanId = loanResponse.getLoanId(); |
| 392 | + |
| 393 | + final PutWorkingCapitalLoansLoanIdRequest modifyRequest = workingCapitalLoanRequestFactory |
| 394 | + .defaultModifyWorkingCapitalLoansRequest(); |
| 395 | + |
| 396 | + final CallFailedRuntimeException exception = fail( |
| 397 | + () -> fineractClient.workingCapitalLoans().modifyWorkingCapitalLoanApplicationById(getCreatedLoanId(), modifyRequest, "")); |
| 398 | + |
| 399 | + assertThat(exception.getStatus()).as("HTTP status code should be 403").isEqualTo(403); |
| 400 | + assertThat(exception.getMessage()).as("Should contain no parameters error") |
| 401 | + .contains(String.format("Working Capital Loan with identifier %d cannot be modified in its current state.", loanId)); |
| 402 | + log.info("Verified modification failed with disbursed Active status empty request"); |
| 403 | + } |
| 404 | + |
381 | 405 | @Then("Working capital loan modification fails with a 404 not found error") |
382 | 406 | public void workingCapitalLoanModificationFailsWith404() { |
383 | 407 | final CallFailedRuntimeException exception = testContext().get(TestContextKey.LOAN_MODIFY_RESPONSE); |
@@ -465,6 +489,137 @@ public void verifyWorkingCapitalLoanUndoApprovalSuccess() { |
465 | 489 | verifyStateTransitionSuccess(TestContextKey.LOAN_UNDO_APPROVAL_RESPONSE, "undo approval"); |
466 | 490 | } |
467 | 491 |
|
| 492 | + @When("Undo approval on the working capital loan results an error with the following data:") |
| 493 | + public void undoApprovalWorkingCapitalLoan(final DataTable table) { |
| 494 | + final PostWorkingCapitalLoansLoanIdRequest undoApprovalRequest = workingCapitalLoanRequestFactory |
| 495 | + .defaultWorkingCapitalLoanUndoApprovalRequest(); |
| 496 | + |
| 497 | + final CallFailedRuntimeException exception = fail(() -> fineractClient.workingCapitalLoans() |
| 498 | + .stateTransitionWorkingCapitalLoanById(getCreatedLoanId(), "undoApproval", undoApprovalRequest)); |
| 499 | + |
| 500 | + verifyErrorResponse(exception, table); |
| 501 | + log.info("Verified working capital loan undo approval failed with expected error"); |
| 502 | + } |
| 503 | + |
| 504 | + @Then("Working Capital loan status will be {string}") |
| 505 | + public void loanWCStatus(String statusExpected) { |
| 506 | + final PostWorkingCapitalLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| 507 | + long loanId = loanResponse.getLoanId(); |
| 508 | + String resourceId = String.valueOf(loanId); |
| 509 | + |
| 510 | + GetWorkingCapitalLoansLoanIdResponse loanDetailsResponse = ok( |
| 511 | + () -> fineractClient.workingCapitalLoans().retrieveWorkingCapitalLoanById(loanId)); |
| 512 | + |
| 513 | + testContext().set(TestContextKey.LOAN_RESPONSE, loanDetailsResponse); |
| 514 | + Long loanStatusActualValue = loanDetailsResponse.getStatus().getId(); |
| 515 | + |
| 516 | + LoanStatus loanStatusExpected = LoanStatus.valueOf(statusExpected); |
| 517 | + Long loanStatusExpectedValue = loanStatusExpected.getValue().longValue(); |
| 518 | + |
| 519 | + assertThat(loanStatusActualValue) |
| 520 | + .as(ErrorMessageHelper.wrongLoanStatus(resourceId, loanStatusActualValue.intValue(), loanStatusExpectedValue.intValue())) |
| 521 | + .isEqualTo(loanStatusExpectedValue); |
| 522 | + } |
| 523 | + |
| 524 | + @And("Admin successfully disburse the Working Capital loan on {string} with {string} EUR transaction amount") |
| 525 | + public void disburseWCLoan(String actualDisbursementDate, String transactionAmount) { |
| 526 | + PostWorkingCapitalLoansLoanIdRequest disburseRequest = workingCapitalLoanRequestFactory.defaultWorkingCapitalLoanDisburseRequest() |
| 527 | + .actualDisbursementDate(actualDisbursementDate)// |
| 528 | + .transactionAmount(new BigDecimal(transactionAmount)); |
| 529 | + |
| 530 | + executeStateTransition("disburse", disburseRequest, TestContextKey.LOAN_DISBURSE_RESPONSE, false); |
| 531 | + verifyStateTransitionSuccess(TestContextKey.LOAN_DISBURSE_RESPONSE, "disbursement"); |
| 532 | + checkChangesExpectedStatus(TestContextKey.LOAN_DISBURSE_RESPONSE, ACTIVE); |
| 533 | + } |
| 534 | + |
| 535 | + @And("Admin successfully disburse the Working Capital loan by externalId on {string} with {string} EUR transaction amount") |
| 536 | + public void disburseWCLoanByExternalId(String actualDisbursementDate, String transactionAmount) { |
| 537 | + PostWorkingCapitalLoansLoanIdRequest disburseRequest = workingCapitalLoanRequestFactory.defaultWorkingCapitalLoanDisburseRequest() |
| 538 | + .actualDisbursementDate(actualDisbursementDate)// |
| 539 | + .transactionAmount(new BigDecimal(transactionAmount)); |
| 540 | + |
| 541 | + executeStateTransition("disburse", disburseRequest, TestContextKey.LOAN_DISBURSE_RESPONSE, true); |
| 542 | + verifyStateTransitionSuccess(TestContextKey.LOAN_DISBURSE_RESPONSE, "disbursement"); |
| 543 | + checkChangesExpectedStatus(TestContextKey.LOAN_DISBURSE_RESPONSE, ACTIVE); |
| 544 | + } |
| 545 | + |
| 546 | + @Then("Verify Working Capital loan disbursement was successful on {string} with {string} EUR transaction amount") |
| 547 | + public void checkDisbursementData(String actualDisbursementDate, String transactionAmount) { |
| 548 | + final PostWorkingCapitalLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| 549 | + long loanId = loanResponse.getLoanId(); |
| 550 | + |
| 551 | + GetWorkingCapitalLoansLoanIdResponse loanDetailsResponse = ok( |
| 552 | + () -> fineractClient.workingCapitalLoans().retrieveWorkingCapitalLoanById(loanId)); |
| 553 | + String getLoanStatus = loanDetailsResponse.getStatus().getValue(); |
| 554 | + assertThat(getLoanStatus.toUpperCase()).isEqualTo(ACTIVE.name()); |
| 555 | + |
| 556 | + GetDisbursementDetail disbursementDetails = loanDetailsResponse.getDisbursementDetails().stream().findFirst() |
| 557 | + .orElseThrow(() -> new RuntimeException("")); |
| 558 | + String formattedDate = disbursementDetails.getActualDisbursementDate().format(FORMATTER); |
| 559 | + assertThat(formattedDate).isEqualTo(actualDisbursementDate); |
| 560 | + assertThat(disbursementDetails.getActualAmount().compareTo(new BigDecimal(transactionAmount))).isEqualTo(0); |
| 561 | + } |
| 562 | + |
| 563 | + @Then("Admin successfully undo Working Capital disbursal") |
| 564 | + public void undoDisbursalWCLoan() { |
| 565 | + PostWorkingCapitalLoansLoanIdRequest undoDisbursalRequest = workingCapitalLoanRequestFactory |
| 566 | + .defaultWorkingCapitalLoanUndoDisburseRequest(); |
| 567 | + |
| 568 | + executeStateTransition("undodisbursal", undoDisbursalRequest, TestContextKey.LOAN_UNDO_DISBURSE_RESPONSE, false); |
| 569 | + verifyStateTransitionSuccess(TestContextKey.LOAN_UNDO_DISBURSE_RESPONSE, "undoDisbursement"); |
| 570 | + checkChangesExpectedStatus(TestContextKey.LOAN_UNDO_DISBURSE_RESPONSE, APPROVED); |
| 571 | + } |
| 572 | + |
| 573 | + @Then("Admin successfully undo Working Capital disbursal by externalId") |
| 574 | + public void undoDisbursalWCLoanByexternalId() { |
| 575 | + PostWorkingCapitalLoansLoanIdRequest undoDisbursalRequest = workingCapitalLoanRequestFactory |
| 576 | + .defaultWorkingCapitalLoanUndoDisburseRequest(); |
| 577 | + |
| 578 | + executeStateTransition("undodisbursal", undoDisbursalRequest, TestContextKey.LOAN_UNDO_DISBURSE_RESPONSE, true); |
| 579 | + verifyStateTransitionSuccess(TestContextKey.LOAN_UNDO_DISBURSE_RESPONSE, "undoDisbursement"); |
| 580 | + checkChangesExpectedStatus(TestContextKey.LOAN_UNDO_DISBURSE_RESPONSE, APPROVED); |
| 581 | + } |
| 582 | + |
| 583 | + @Then("Admin fails to disburse the Working Capital loan on {string} with {string} EUR transaction amount because of not approved") |
| 584 | + public void disburseWCLoanFailureWithNotApproved(String actualDisbursementDate, String transactionAmount) { |
| 585 | + final PostWorkingCapitalLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| 586 | + long loanId = loanResponse.getLoanId(); |
| 587 | + PostWorkingCapitalLoansLoanIdRequest disburseRequest = workingCapitalLoanRequestFactory.defaultWorkingCapitalLoanDisburseRequest() |
| 588 | + .actualDisbursementDate(actualDisbursementDate).transactionAmount(new BigDecimal(transactionAmount)); |
| 589 | + |
| 590 | + CallFailedRuntimeException exception = fail(() -> fineractClient.workingCapitalLoans().stateTransitionWorkingCapitalLoanById(loanId, |
| 591 | + disburseRequest, Map.of("command", "disburse"))); |
| 592 | + assertThat(exception.getStatus()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(400); |
| 593 | + assertThat(exception.getDeveloperMessage()) |
| 594 | + .contains(ErrorMessageHelper.disburseNotApprovedFailure(SUBMITTED_AND_PENDING_APPROVAL.name())); |
| 595 | + } |
| 596 | + |
| 597 | + @Then("Admin fails to disburse the Working Capital loan on {string} with {string} EUR transaction amount with invalid data outcomes with error message {string}") |
| 598 | + public void disburseWCLoanFailureWithInvalidData(String actualDisbursementDate, String transactionAmount, |
| 599 | + String errorMessageDescription) { |
| 600 | + String errorMessage = ErrorMessageHelper.disburseDateFailure(errorMessageDescription); |
| 601 | + disburseWCLoanFailure(actualDisbursementDate, transactionAmount, 400, errorMessage); |
| 602 | + } |
| 603 | + |
| 604 | + @Then("Admin fails to disburse the Working Capital loan on {string} with {string} EUR transaction amount without mandatory data outcomes with error message {string}") |
| 605 | + public void disburseWCLoanFailureWithoutMandatoryData(String actualDisbursementDate, String transactionAmount, String errorMessage) { |
| 606 | + disburseWCLoanFailure(actualDisbursementDate, transactionAmount, 400, errorMessage); |
| 607 | + } |
| 608 | + |
| 609 | + @Then("Admin fails to undo disbursal the Working Capital loan due to loan status {string}") |
| 610 | + public void undoDisbursalWCLoanFailure(String actualLoanStatus) { |
| 611 | + final PostWorkingCapitalLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| 612 | + long loanId = loanResponse.getLoanId(); |
| 613 | + |
| 614 | + PostWorkingCapitalLoansLoanIdRequest undoDisbursalRequest = workingCapitalLoanRequestFactory |
| 615 | + .defaultWorkingCapitalLoanUndoDisburseRequest(); |
| 616 | + |
| 617 | + CallFailedRuntimeException exception = fail(() -> fineractClient.workingCapitalLoans().stateTransitionWorkingCapitalLoanById(loanId, |
| 618 | + undoDisbursalRequest, Map.of("command", "undodisbursal"))); |
| 619 | + assertThat(exception.getStatus()).as(ErrorMessageHelper.undoDisbursalDisallowedFailure(actualLoanStatus)).isEqualTo(400); |
| 620 | + assertThat(exception.getDeveloperMessage()).contains(ErrorMessageHelper.undoDisbursalDisallowedFailure(actualLoanStatus)); |
| 621 | + } |
| 622 | + |
468 | 623 | // ==================================== |
469 | 624 | // Private Helper Methods |
470 | 625 | // ==================================== |
@@ -668,4 +823,27 @@ private void verifyErrorResponse(final CallFailedRuntimeException exception, fin |
668 | 823 | .isEqualTo(Integer.parseInt(expectedHttpCode)); |
669 | 824 | assertThat(exception.getMessage()).as("Should contain error message").contains(expectedErrorMessage); |
670 | 825 | } |
| 826 | + |
| 827 | + public void checkChangesExpectedStatus(String responseKey, LoanStatus expectedStatus) { |
| 828 | + final PostWorkingCapitalLoansLoanIdResponse response = testContext().get(responseKey); |
| 829 | + final Object changes = response.getChanges(); |
| 830 | + assertThat(changes).as("Changes map").isNotNull().isInstanceOf(Map.class); |
| 831 | + |
| 832 | + @SuppressWarnings("unchecked") |
| 833 | + final Map<String, Object> changesMap = (Map<String, Object>) changes; |
| 834 | + assertThat(changesMap).as("Changes map should contain value '%s'", expectedStatus).containsValue(expectedStatus.name()); |
| 835 | + } |
| 836 | + |
| 837 | + public void disburseWCLoanFailure(String actualDisbursementDate, String transactionAmount, int errorCode, String errorMessage) { |
| 838 | + final PostWorkingCapitalLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| 839 | + long loanId = loanResponse.getLoanId(); |
| 840 | + PostWorkingCapitalLoansLoanIdRequest disburseRequest = workingCapitalLoanRequestFactory.defaultWorkingCapitalLoanDisburseRequest() |
| 841 | + .actualDisbursementDate(actualDisbursementDate).transactionAmount(new BigDecimal(transactionAmount)); |
| 842 | + |
| 843 | + CallFailedRuntimeException exception = fail(() -> fineractClient.workingCapitalLoans().stateTransitionWorkingCapitalLoanById(loanId, |
| 844 | + disburseRequest, Map.of("command", "disburse"))); |
| 845 | + assertThat(exception.getStatus()).as(errorMessage).isEqualTo(errorCode); |
| 846 | + assertThat(exception.getDeveloperMessage()).contains(errorMessage); |
| 847 | + } |
| 848 | + |
671 | 849 | } |
0 commit comments