FINERACT-2070: Update test configurations

This commit is contained in:
Adam Saghy
2024-11-09 20:04:13 +01:00
parent 17a4392c26
commit 64976f1eb4
28 changed files with 1021 additions and 362 deletions
+4 -2
View File
@@ -25,7 +25,7 @@ jobs:
- name: Build the image
run: ./gradlew --no-daemon --console=plain :fineract-provider:clean :fineract-provider:build :fineract-provider:jibDockerBuild -x test -x cucumber
- name: Start the Fineract stack
run: docker compose -f docker-compose-postgresql.yml up -d
run: docker compose -f docker-compose-postgresql-test-activemq.yml up -d
- name: Wait for stack to come up
run: sleep 400
- name: Check the stack
@@ -39,5 +39,7 @@ jobs:
TEST_PASSWORD: password
TEST_TENANT_ID: default
INITIALIZATION_ENABLED: true
EVENT_VERIFICATION_ENABLED: false
EVENT_VERIFICATION_ENABLED: true
ACTIVEMQ_BROKER_URL: tcp://localhost:61616
ACTIVEMQ_TOPIC_NAME: events
run: ./gradlew --no-daemon --console=plain fineract-e2e-tests-runner:cucumber --tags 'not @Skip' allureReport
+5
View File
@@ -17,5 +17,10 @@
# under the License.
#
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_SPRING_EVENTS_ENABLED=false
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_ENABLED=true
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_BROKER_URL=tcp://activemq:61616
FINERACT_EXTERNAL_EVENTS_ENABLED=true
FINERACT_EXTERNAL_EVENTS_PRODUCER_JMS_ENABLED=true
FINERACT_EXTERNAL_EVENTS_PRODUCER_JMS_TOPIC_NAME=events
FINERACT_EXTERNAL_EVENTS_PRODUCER_JMS_BROKER_URL=tcp://activemq:61616
+1 -1
View File
@@ -52,7 +52,7 @@ FINERACT_DEFAULT_TENANTDB_PWD=skdcnwauicn2ucnaecasdsajdnizucawencascdca
FINERACT_DEFAULT_MASTER_PASSWORD=fineract
FINERACT_MANAGEMENT_ENDPOINT_WEB_EXPOSURE_INCLUDE=health,info,prometheus
FINERACT_MANAGEMENT_METRICS_TAGS_APPLICATION=fineract
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_SPRING_EVENTS_ENABLED=false
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_SPRING_EVENTS_ENABLED=true
FINERACT_INSECURE_HTTP_CLIENT=true
SPRING_PROFILES_ACTIVE=test,diagnostics
OTEL_SERVICE_NAME=fineract
+1
View File
@@ -17,6 +17,7 @@
# under the License.
#
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_SPRING_EVENTS_ENABLED=false
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_ENABLED=false
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_ENABLED=true
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_BOOTSTRAP_SERVERS=b-3-public.democluster1.am2oyx.c4.kafka.eu-central-1.amazonaws.com:9198,b-2-public.democluster1.am2oyx.c4.kafka.eu-central-1.amazonaws.com:9198,b-1-public.democluster1.am2oyx.c4.kafka.eu-central-1.amazonaws.com:9198
+1
View File
@@ -17,6 +17,7 @@
# under the License.
#
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_SPRING_EVENTS_ENABLED=false
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_ENABLED=false
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_ENABLED=true
FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_BOOTSTRAP_SERVERS=kafka:9092
@@ -0,0 +1,45 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
version: "3.8"
services:
activemq:
extends:
file: ./config/docker/compose/activemq.yml
service: activemq
db:
extends:
file: ./config/docker/compose/postgresql.yml
service: postgresql
fineract:
extends:
file: ./config/docker/compose/fineract.yml
service: fineract
ports:
- "8443:8443"
depends_on:
db:
condition: service_healthy
env_file:
- ./config/docker/env/fineract.env
- ./config/docker/env/fineract-common.env
- ./config/docker/env/fineract-postgresql.env
- ./config/docker/env/activemq.env
@@ -1006,7 +1006,7 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
.name(name48)//
.supportedInterestRefundTypes(Arrays.asList("MERCHANT_ISSUED_REFUND", "PAYOUT_REFUND"))//
.paymentAllocation(List.of(//
createPaymentAllocation("DEFAULT", "LAST_INSTALLMENT")));//
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT")));//
Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvancedpaymentInterestEmiActualActualInterestRefundInterestRecalculation = loanProductsApi
.createLoanProduct(loanProductsRequestLP2AdvancedpaymentInterestEmiActualActualInterestRefundRecalculation).execute();
TestContext.INSTANCE.set(
@@ -101,7 +101,7 @@ public class EventAssertion {
} else {
eventMessage = (EventMessage<R>) new EmptyEventMessage();
}
log.info("Assert event: {}", eventMessage.getIdempotencyKey());
log.debug("Assert event: {}", eventMessage.getIdempotencyKey());
return new EventAssertionBuilder<>(eventMessage);
}
@@ -167,7 +167,11 @@ public class EventAssertion {
public EventAssertionBuilder<R> isEqualTo(BigDecimal value) {
if (eventProperties.isEventVerificationEnabled()) {
Assertions.assertThat(extractedValue).isEqualByComparingTo(value);
if (extractedValue == null) {
Assertions.assertThat(extractedValue).isEqualTo(value);
} else {
Assertions.assertThat(extractedValue).isEqualByComparingTo(value);
}
}
return new EventAssertionBuilder<>(eventMessage);
}
@@ -128,9 +128,8 @@ public class EventCheckHelper {
eventAssertion.assertEvent(LoanCreatedEvent.class, createLoanResponse.body().getLoanId())//
.extractingData(LoanAccountDataV1::getId).isEqualTo(body.getId())//
.extractingData(loanAccountDataV1 -> loanAccountDataV1.getStatus().getId()).isEqualTo(body.getStatus().getId())//
.extractingData(LoanAccountDataV1::getClientId).isEqualTo(Long.valueOf(body.getClientId()))//
.extractingData(loanAccountDataV1 -> loanAccountDataV1.getPrincipal().longValue())
.isEqualTo(body.getPrincipal().longValue())//
.extractingData(LoanAccountDataV1::getClientId).isEqualTo(body.getClientId())//
.extractingBigDecimal(LoanAccountDataV1::getPrincipal).isEqualTo(body.getPrincipal())//
.extractingData(loanAccountDataV1 -> loanAccountDataV1.getSummary().getCurrency().getCode())
.isEqualTo(body.getCurrency().getCode());//
}
@@ -145,8 +144,7 @@ public class EventCheckHelper {
.extractingData(loanAccountDataV1 -> loanAccountDataV1.getStatus().getId()).isEqualTo(body.getStatus().getId())//
.extractingData(loanAccountDataV1 -> loanAccountDataV1.getStatus().getCode()).isEqualTo(body.getStatus().getCode())//
.extractingData(LoanAccountDataV1::getClientId).isEqualTo(Long.valueOf(body.getClientId()))//
.extractingData(loanAccountDataV1 -> loanAccountDataV1.getApprovedPrincipal().longValue())
.isEqualTo(body.getApprovedPrincipal().longValue())//
.extractingBigDecimal(LoanAccountDataV1::getApprovedPrincipal).isEqualTo(BigDecimal.valueOf(body.getApprovedPrincipal()))//
.extractingData(loanAccountDataV1 -> loanAccountDataV1.getTimeline().getApprovedOnDate())//
.isEqualTo(FORMATTER_EVENTS.format(body.getTimeline().getApprovedOnDate()))//
.extractingData(loanAccountDataV1 -> loanAccountDataV1.getSummary().getCurrency().getCode())
@@ -239,9 +237,9 @@ public class EventCheckHelper {
}
private boolean areBigDecimalValuesEqual(BigDecimal actual, BigDecimal expected) {
log.info("--- Checking BigDecimal values.... ---");
log.info("Actual: {}", actual);
log.info("Expected: {}", expected);
log.debug("--- Checking BigDecimal values.... ---");
log.debug("Actual: {}", actual);
log.debug("Expected: {}", expected);
return actual.compareTo(expected) == 0;
}
@@ -261,8 +259,7 @@ public class EventCheckHelper {
eventAssertion.assertEvent(LoanDisbursalTransactionEvent.class, disbursementTransaction.getId())//
.extractingData(LoanTransactionDataV1::getLoanId).isEqualTo(body.getId())//
.extractingData(LoanTransactionDataV1::getDate).isEqualTo(FORMATTER_EVENTS.format(disbursementTransaction.getDate()))//
.extractingData(loanTransactionDataV1 -> loanTransactionDataV1.getAmount().longValue())
.isEqualTo(disbursementTransaction.getAmount().longValue());//
.extractingBigDecimal(LoanTransactionDataV1::getAmount).isEqualTo(BigDecimal.valueOf(disbursementTransaction.getAmount()));//
}
public EventAssertion.EventAssertionBuilder<LoanTransactionDataV1> transactionEventCheck(
@@ -291,8 +288,7 @@ public class EventCheckHelper {
EventAssertion.EventAssertionBuilder<LoanTransactionDataV1> eventBuilder = eventAssertion.assertEvent(eventClass, transactionId);
eventBuilder.extractingData(LoanTransactionDataV1::getLoanId).isEqualTo(loanDetailsResponse.body().getId())//
.extractingData(LoanTransactionDataV1::getDate).isEqualTo(FORMATTER_EVENTS.format(transactionFound.getDate()))//
.extractingData(loanTransactionDataV1 -> loanTransactionDataV1.getAmount().longValue())
.isEqualTo(transactionFound.getAmount().longValue())//
.extractingBigDecimal(LoanTransactionDataV1::getAmount).isEqualTo(BigDecimal.valueOf(transactionFound.getAmount()))//
.extractingData(LoanTransactionDataV1::getExternalOwnerId).isEqualTo(externalOwnerId);//
return eventBuilder;
}
@@ -316,13 +312,15 @@ public class EventCheckHelper {
.isEqualTo(filtered.getOwner().getExternalId()).extractingData(LoanOwnershipTransferDataV1::getTransferExternalId)
.isEqualTo(filtered.getTransferExternalId()).extractingData(LoanOwnershipTransferDataV1::getSettlementDate)
.isEqualTo(FORMATTER_EVENTS.format(filtered.getSettlementDate()))
.extractingData(LoanOwnershipTransferDataV1::getTotalOutstandingBalanceAmount)
.extractingBigDecimal(LoanOwnershipTransferDataV1::getTotalOutstandingBalanceAmount)
.isEqualTo(totalOutstandingBalanceAmountExpected)
.extractingData(LoanOwnershipTransferDataV1::getOutstandingPrincipalPortion).isEqualTo(outstandingPrincipalPortionExpected)
.extractingData(LoanOwnershipTransferDataV1::getOutstandingFeePortion).isEqualTo(outstandingFeePortionExpected)
.extractingData(LoanOwnershipTransferDataV1::getOutstandingPenaltyPortion).isEqualTo(outstandingPenaltyPortionExpected)
.extractingData(LoanOwnershipTransferDataV1::getOutstandingInterestPortion).isEqualTo(outstandingInterestPortionExpected)
.extractingData(LoanOwnershipTransferDataV1::getOverPaymentPortion).isEqualTo(overPaymentPortionExpected);
.extractingBigDecimal(LoanOwnershipTransferDataV1::getOutstandingPrincipalPortion)
.isEqualTo(outstandingPrincipalPortionExpected).extractingBigDecimal(LoanOwnershipTransferDataV1::getOutstandingFeePortion)
.isEqualTo(outstandingFeePortionExpected).extractingBigDecimal(LoanOwnershipTransferDataV1::getOutstandingPenaltyPortion)
.isEqualTo(outstandingPenaltyPortionExpected)
.extractingBigDecimal(LoanOwnershipTransferDataV1::getOutstandingInterestPortion)
.isEqualTo(outstandingInterestPortionExpected).extractingBigDecimal(LoanOwnershipTransferDataV1::getOverPaymentPortion)
.isEqualTo(overPaymentPortionExpected);
}
public void loanOwnershipTransferBusinessEventWithStatusCheck(Long loanId, Long transferId, String transferStatus,
@@ -358,15 +356,17 @@ public class EventCheckHelper {
.isEqualTo(filtered.getOwner().getExternalId()).extractingData(LoanOwnershipTransferDataV1::getTransferExternalId)
.isEqualTo(filtered.getTransferExternalId()).extractingData(LoanOwnershipTransferDataV1::getSettlementDate)
.isEqualTo(FORMATTER_EVENTS.format(filtered.getSettlementDate()))
.extractingData(LoanOwnershipTransferDataV1::getTotalOutstandingBalanceAmount)
.extractingBigDecimal(LoanOwnershipTransferDataV1::getTotalOutstandingBalanceAmount)
.isEqualTo(totalOutstandingBalanceAmountExpected)
.extractingData(LoanOwnershipTransferDataV1::getOutstandingPrincipalPortion).isEqualTo(outstandingPrincipalPortionExpected)
.extractingData(LoanOwnershipTransferDataV1::getOutstandingFeePortion).isEqualTo(outstandingFeePortionExpected)
.extractingData(LoanOwnershipTransferDataV1::getOutstandingPenaltyPortion).isEqualTo(outstandingPenaltyPortionExpected)
.extractingData(LoanOwnershipTransferDataV1::getOutstandingInterestPortion).isEqualTo(outstandingInterestPortionExpected)
.extractingData(LoanOwnershipTransferDataV1::getOverPaymentPortion).isEqualTo(overPaymentPortionExpected)
.extractingData(LoanOwnershipTransferDataV1::getTransferStatus).isEqualTo(transferStatusExpected)
.extractingData(LoanOwnershipTransferDataV1::getTransferStatusReason).isEqualTo(transferStatusReasonExpected);
.extractingBigDecimal(LoanOwnershipTransferDataV1::getOutstandingPrincipalPortion)
.isEqualTo(outstandingPrincipalPortionExpected).extractingBigDecimal(LoanOwnershipTransferDataV1::getOutstandingFeePortion)
.isEqualTo(outstandingFeePortionExpected).extractingBigDecimal(LoanOwnershipTransferDataV1::getOutstandingPenaltyPortion)
.isEqualTo(outstandingPenaltyPortionExpected)
.extractingBigDecimal(LoanOwnershipTransferDataV1::getOutstandingInterestPortion)
.isEqualTo(outstandingInterestPortionExpected).extractingBigDecimal(LoanOwnershipTransferDataV1::getOverPaymentPortion)
.isEqualTo(overPaymentPortionExpected).extractingData(LoanOwnershipTransferDataV1::getTransferStatus)
.isEqualTo(transferStatusExpected).extractingData(LoanOwnershipTransferDataV1::getTransferStatusReason)
.isEqualTo(transferStatusReasonExpected);
}
public void loanAccountSnapshotBusinessEventCheck(Long loanId, Long transferId) throws IOException {
@@ -389,17 +389,17 @@ public class EventCheckHelper {
eventAssertion.assertEvent(LoanAccountSnapshotEvent.class, loanId).extractingData(LoanAccountDataV1::getId).isEqualTo(loanId)
.extractingData(LoanAccountDataV1::getExternalOwnerId).isEqualTo(ownerExternalIdExpected)
.extractingData(LoanAccountDataV1::getSettlementDate).isEqualTo(settlementDateExpected)
.extractingData(loanAccountDataV1 -> loanAccountDataV1.getSummary().getTotalOutstanding())
.extractingBigDecimal(loanAccountDataV1 -> loanAccountDataV1.getSummary().getTotalOutstanding())
.isEqualTo(totalOutstandingBalanceAmountExpected)
.extractingData(loanAccountDataV1 -> loanAccountDataV1.getSummary().getPrincipalOutstanding())
.extractingBigDecimal(loanAccountDataV1 -> loanAccountDataV1.getSummary().getPrincipalOutstanding())
.isEqualTo(outstandingPrincipalPortionExpected)
.extractingData(loanAccountDataV1 -> loanAccountDataV1.getSummary().getFeeChargesOutstanding())
.extractingBigDecimal(loanAccountDataV1 -> loanAccountDataV1.getSummary().getFeeChargesOutstanding())
.isEqualTo(outstandingFeePortionExpected)
.extractingData(loanAccountDataV1 -> loanAccountDataV1.getSummary().getPenaltyChargesOutstanding())
.extractingBigDecimal(loanAccountDataV1 -> loanAccountDataV1.getSummary().getPenaltyChargesOutstanding())
.isEqualTo(outstandingPenaltyPortionExpected)
.extractingData(loanAccountDataV1 -> loanAccountDataV1.getSummary().getInterestOutstanding())
.extractingBigDecimal(loanAccountDataV1 -> loanAccountDataV1.getSummary().getInterestOutstanding())
.isEqualTo(outstandingInterestPortionExpected)
.extractingData(loanAccountDataV1 -> loanAccountDataV1.getSummary().getTotalOverdue())
.extractingBigDecimal(loanAccountDataV1 -> loanAccountDataV1.getSummary().getTotalOverdue())
.isEqualTo(overPaymentPortionExpected);
}
@@ -435,15 +435,15 @@ public class EventCheckHelper {
pausePeriodEndExpected))//
.isEqualTo(pausePeriodEndExpected);//
log.info("LoanAccountDelinquencyPauseChangedBusinessEvent -> isActiveActual:\s{}", isActiveActual);
log.info("LoanAccountDelinquencyPauseChangedBusinessEvent -> pausePeriodStartActual:\s{}", pausePeriodStartActual);
log.info("LoanAccountDelinquencyPauseChangedBusinessEvent -> pausePeriodEndActual:\s{}", pausePeriodEndActual);
log.debug("LoanAccountDelinquencyPauseChangedBusinessEvent -> isActiveActual:\s{}", isActiveActual);
log.debug("LoanAccountDelinquencyPauseChangedBusinessEvent -> pausePeriodStartActual:\s{}", pausePeriodStartActual);
log.debug("LoanAccountDelinquencyPauseChangedBusinessEvent -> pausePeriodEndActual:\s{}", pausePeriodEndActual);
}
return null;
});
}
public void installmentLevelDelinquencyRangeChangeEventCheck(Long loanId) throws IOException {
public void installmentLevelDelinquencyRangeChangeEventCheck(Long loanId) {
eventAssertion.assertEvent(LoanDelinquencyRangeChangeEvent.class, loanId).extractingData(loanAccountDelinquencyRangeDataV1 -> {
// check if sum of total amounts equal the sum of amount types in installmentDelinquencyBuckets
BigDecimal totalAmountSum = loanAccountDelinquencyRangeDataV1.getInstallmentDelinquencyBuckets().stream()//
@@ -471,13 +471,13 @@ public class EventCheckHelper {
assertThat(totalAmountSum)
.as(ErrorMessageHelper.wrongAmountInLoanDelinquencyRangeChangedEventTotalAmount(totalAmountSum, totalAmountSumActual))
.isEqualTo(totalAmountSumActual);
.isEqualByComparingTo(totalAmountSumActual);
log.info("Nr of installment level delinquency buckets: {}",
log.debug("Nr of installment level delinquency buckets: {}",
loanAccountDelinquencyRangeDataV1.getInstallmentDelinquencyBuckets().size());
log.info("Buckets:");
log.debug("Buckets:");
loanAccountDelinquencyRangeDataV1.getInstallmentDelinquencyBuckets().forEach(e -> {
log.info("{}\s-\sTotal amount:\s{}", e.getDelinquencyRange().getClassification(), e.getAmount().getTotalAmount());
log.debug("{}\s-\sTotal amount:\s{}", e.getDelinquencyRange().getClassification(), e.getAmount().getTotalAmount());
});
return null;
@@ -62,7 +62,10 @@ public class JobService {
private void waitUntilJobIsFinished(Job job) {
String jobName = job.getName();
await().atMost(Duration.ofMinutes(2)).alias("%s didn't finish on time".formatted(jobName)).pollInterval(Duration.ofSeconds(10))
await().atMost(Duration.ofMinutes(2)) //
.alias("%s didn't finish on time".formatted(jobName)) //
.pollInterval(Duration.ofSeconds(5)) //
.pollDelay(Duration.ofSeconds(5)) //
.until(() -> {
log.info("Waiting for job {} to finish", jobName);
Long jobId = jobResolver.resolve(job);
@@ -253,10 +253,10 @@ public class AssetExternalizationStepDef extends AbstractStepDef {
Long loanIdActual = body.getSubResourceId();
String transferExternalIdActual = body.getResourceExternalId();
log.info("loanId: {}", loanId);
log.info("ownerExternalIdStored: {}", ownerExternalIdStored);
log.info("transferExternalId generated by user: {}", transferExternalIdExpected);
log.info("transferExternalIdActual: {}", transferExternalIdActual);
log.debug("loanId: {}", loanId);
log.debug("ownerExternalIdStored: {}", ownerExternalIdStored);
log.debug("transferExternalId generated by user: {}", transferExternalIdExpected);
log.debug("transferExternalIdActual: {}", transferExternalIdActual);
assertThat(loanIdActual).as(ErrorMessageHelper.wrongDataInAssetExternalizationResponse(loanIdActual, loanId)).isEqualTo(loanId);
assertThat(body.getResourceId()).isNotNull();
@@ -405,8 +405,8 @@ public class AssetExternalizationStepDef extends AbstractStepDef {
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
.isEqualTo(errorMessageExpected);
log.info("ERROR CODE: {}", errorCodeActual);
log.info("ERROR MESSAGE: {}", errorMessageActual);
log.debug("ERROR CODE: {}", errorCodeActual);
log.debug("ERROR MESSAGE: {}", errorMessageActual);
}
@Then("Asset externalization transaction with the following data results a {int} error and {string} error message")
@@ -453,8 +453,8 @@ public class AssetExternalizationStepDef extends AbstractStepDef {
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
.isEqualTo(errorMessageExpected);
log.info("ERROR CODE: {}", errorCodeActual);
log.info("ERROR MESSAGE: {}", errorMessageActual);
log.debug("ERROR CODE: {}", errorCodeActual);
log.debug("ERROR MESSAGE: {}", errorMessageActual);
}
@Then("Asset externalization SALES transaction with ownerExternalId = null and the following data results a {int} error and {string} error message")
@@ -488,8 +488,8 @@ public class AssetExternalizationStepDef extends AbstractStepDef {
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
.isEqualTo(errorMessageExpected);
log.info("ERROR CODE: {}", errorCodeActual);
log.info("ERROR MESSAGE: {}", errorMessageActual);
log.debug("ERROR CODE: {}", errorCodeActual);
log.debug("ERROR MESSAGE: {}", errorMessageActual);
}
@Then("The latest asset externalization transaction with {string} status has the following TRANSFER Journal entries:")
@@ -528,10 +528,10 @@ public class AssetExternalizationStepDef extends AbstractStepDef {
.isEqualTo(linesExpected);
}
log.info("loanId: {}", journalEntriesOfTransfer.body().getTransferData().getLoan().getLoanId());
log.info("ownerExternalId: {}", journalEntriesOfTransfer.body().getTransferData().getOwner().getExternalId());
log.info("transferId: {}", lastTransferIdByStatus);
log.info("transferExternalId: {}", journalEntriesOfTransfer.body().getTransferData().getTransferExternalId());
log.debug("loanId: {}", journalEntriesOfTransfer.body().getTransferData().getLoan().getLoanId());
log.debug("ownerExternalId: {}", journalEntriesOfTransfer.body().getTransferData().getOwner().getExternalId());
log.debug("transferId: {}", lastTransferIdByStatus);
log.debug("transferExternalId: {}", journalEntriesOfTransfer.body().getTransferData().getTransferExternalId());
}
private Long getLastTransferIdByStatus(Long loanId, String status) throws IOException {
@@ -589,7 +589,7 @@ public class AssetExternalizationStepDef extends AbstractStepDef {
.isEqualTo(linesExpected);
}
log.info("ownerExternalId: {}", journalEntriesOfOwner.body().getOwnerData().getExternalId());
log.debug("ownerExternalId: {}", journalEntriesOfOwner.body().getOwnerData().getExternalId());
}
@Then("LoanOwnershipTransferBusinessEvent is created")
@@ -633,10 +633,10 @@ public class AssetExternalizationStepDef extends AbstractStepDef {
Long loanIdActual = body.getSubResourceId();
String transferExternalIdActual = body.getResourceExternalId();
log.info("loanId: {}", loanId);
log.info("ownerExternalIdStored: {}", ownerExternalIdStored);
log.info("transferExternalId generated by user: {}", transferExternalIdExpected);
log.info("transferExternalIdActual: {}", transferExternalIdActual);
log.debug("loanId: {}", loanId);
log.debug("ownerExternalIdStored: {}", ownerExternalIdStored);
log.debug("transferExternalId generated by user: {}", transferExternalIdExpected);
log.debug("transferExternalIdActual: {}", transferExternalIdActual);
assertThat(loanIdActual).as(ErrorMessageHelper.wrongDataInAssetExternalizationResponse(loanIdActual, loanId)).isEqualTo(loanId);
assertThat(body.getResourceId()).isNotNull();
@@ -488,11 +488,11 @@ public class BatchApiStepDef extends AbstractStepDef {
.execute();
if (batchResponseList.errorBody() != null) {
log.info("ERROR: {}", batchResponseList.errorBody().string());
log.debug("ERROR: {}", batchResponseList.errorBody().string());
}
if (batchResponseList.body() != null) {
log.info("Body: {}", batchResponseList.body());
log.debug("Body: {}", batchResponseList.body());
}
testContext().set(TestContextKey.BATCH_API_CALL_RESPONSE, batchResponseList);
@@ -554,8 +554,8 @@ public class BatchApiStepDef extends AbstractStepDef {
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
.isEqualTo(errorMessageExpected);
log.info("ERROR CODE: {}", errorCodeActual);
log.info("ERROR MESSAGE: {}", errorMessageActual);
log.debug("ERROR CODE: {}", errorCodeActual);
log.debug("ERROR MESSAGE: {}", errorMessageActual);
}
@When("Batch API call with steps: queryDatatable, updateDatatable runs, with empty queryDatatable response")
@@ -150,7 +150,7 @@ public class BusinessStepStepDef extends AbstractStepDef {
}
private void setBackBusinessStepsToOriginal() throws IOException {
log.info("Setting back Business steps to original...");
log.debug("Setting back Business steps to original...");
UpdateBusinessStepConfigRequest request = new UpdateBusinessStepConfigRequest().businessSteps(ORIGINAL_COB_BUSINESS_STEPS);
Response<Void> response = businessStepConfigurationApi.updateJobBusinessStepConfig(WORKFLOW_NAME_LOAN_CLOSE_OF_BUSINESS, request)
@@ -172,7 +172,7 @@ public class BusinessStepStepDef extends AbstractStepDef {
.map(BusinessStep::getStepName)//
.collect(Collectors.toList());//
log.info("Business steps has been CHANGED to the following:");
changes.forEach(e -> log.info(e));
log.debug("Business steps has been CHANGED to the following:");
changes.forEach(e -> log.debug(e));
}
}
@@ -60,8 +60,8 @@ public class LoanCOBStepDef extends AbstractStepDef {
LocalDate cobDate = response.body().getCobBusinessDate();
LocalDate cobDateMinusOne = cobDate.minusDays(1);
LocalDate cobProcessedDate = response.body().getCobProcessedDate();
log.info("cobDateMinusOne: {}", cobDateMinusOne);
log.info("cobProcessedDate: {}", cobProcessedDate);
log.debug("cobDateMinusOne: {}", cobDateMinusOne);
log.debug("cobProcessedDate: {}", cobProcessedDate);
boolean result = cobDateMinusOne.isAfter(cobProcessedDate);
assertThat(result).as(ErrorMessageHelper.wrongLastCOBProcessedLoanDate(cobProcessedDate, cobDateMinusOne)).isTrue();
@@ -74,7 +74,7 @@ public class LoanCOBStepDef extends AbstractStepDef {
int size = response.body().getContent().size();
assertThat(size).as(ErrorMessageHelper.listOfLockedLoansNotEmpty(response)).isEqualTo(0);
log.info("Size of List of the locked loans: {}", size);
log.debug("Size of List of the locked loans: {}", size);
}
@Then("The loan account is not locked")
@@ -118,8 +118,8 @@ public class LoanChargeAdjustmentStepDef extends AbstractStepDef {
.as(ErrorMessageHelper.wrongErrorMessageInFailedChargeAdjustment(developerMessageActual, developerMessageExpected))
.isEqualTo(developerMessageExpected);
log.info("Error code: {}", httpStatusCodeActual);
log.info("Error message: {}", developerMessageActual);
log.debug("Error code: {}", httpStatusCodeActual);
log.debug("Error message: {}", developerMessageActual);
}
@When("Admin reverts the charge adjustment which was raised on {string} with {double} EUR transaction amount")
@@ -26,6 +26,7 @@ import io.cucumber.java.en.And;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.format.DateTimeFormatter;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
@@ -258,9 +259,9 @@ public class LoanChargeStepDef extends AbstractStepDef {
GetLoansLoanIdChargesChargeIdResponse body = chargeDetails.body();
eventAssertion.assertEvent(LoanAddChargeEvent.class, loanChargeResponse.body().getResourceId())
.extractingData(LoanChargeDataV1::getName).isEqualTo(body.getName())
.extractingData(loanChargeDataV1 -> loanChargeDataV1.getAmount().longValue()).isEqualTo(body.getAmount().longValue())
.extractingData(LoanChargeDataV1::getDueDate).isEqualTo(formatter.format(body.getDueDate()));
.extractingData(LoanChargeDataV1::getName).isEqualTo(body.getName()).extractingBigDecimal(LoanChargeDataV1::getAmount)
.isEqualTo(BigDecimal.valueOf(body.getAmount())).extractingData(LoanChargeDataV1::getDueDate)
.isEqualTo(formatter.format(body.getDueDate()));
}
@Then("Loan charge transaction with the following data results a {int} error and {string} error message")
@@ -300,7 +301,7 @@ public class LoanChargeStepDef extends AbstractStepDef {
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
.isEqualTo(errorMessageExpected);
log.info("ERROR CODE: {}", errorCodeActual);
log.info("ERROR MESSAGE: {}", errorMessageActual);
log.debug("ERROR CODE: {}", errorCodeActual);
log.debug("ERROR MESSAGE: {}", errorMessageActual);
}
}
@@ -273,8 +273,8 @@ public class LoanDelinquencyStepDef extends AbstractStepDef {
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
.isEqualTo(errorMessageExpected);
log.info("ERROR CODE: {}", errorCodeActual);
log.info("ERROR MESSAGE: {}", errorMessageActual);
log.debug("ERROR CODE: {}", errorCodeActual);
log.debug("ERROR MESSAGE: {}", errorMessageActual);
}
@When("Admin initiate a DELINQUENCY RESUME with startDate: {string}")
@@ -657,7 +657,7 @@ public class LoanDelinquencyStepDef extends AbstractStepDef {
Long loanLevelDelinquencyRangeIdExpected = delinquencyRange.getId();
String loanLevelDelinquencyRangeExpected = delinquencyRange.getClassification();
String loanLevelDelinquentDateExpected = FORMATTER.format(delinquent.getDelinquentDate());
BigDecimal loanLevelTotalAmountExpected = new BigDecimal(delinquent.getDelinquentAmount());
BigDecimal loanLevelTotalAmountExpected = BigDecimal.valueOf(delinquent.getDelinquentAmount());
assertThat(loanLevelDelinquencyRangeId)//
.as(ErrorMessageHelper.wrongValueInLoanDelinquencyRangeChangeBusinessEvent4(loanLevelDelinquencyRangeId,
@@ -674,7 +674,7 @@ public class LoanDelinquencyStepDef extends AbstractStepDef {
assertThat(loanLevelTotalAmount)//
.as(ErrorMessageHelper.wrongValueInLoanDelinquencyRangeChangeBusinessEvent6(loanLevelTotalAmount,
loanLevelTotalAmountExpected))//
.isEqualTo(loanLevelTotalAmountExpected);//
.isEqualByComparingTo(loanLevelTotalAmountExpected);//
List<GetLoansLoanIdLoanInstallmentLevelDelinquency> installmentLevelDelinquencyBucketsExpected = delinquent
.getInstallmentLevelDelinquency();
@@ -703,7 +703,7 @@ public class LoanDelinquencyStepDef extends AbstractStepDef {
assertThat(installmentLevelTotalAmount)//
.as(ErrorMessageHelper.wrongValueInLoanDelinquencyRangeChangeBusinessEvent3(installmentLevelTotalAmount,
installmentLevelTotalAmountExpected))//
.isEqualTo(installmentLevelTotalAmountExpected);//
.isEqualByComparingTo(installmentLevelTotalAmountExpected);//
}
return null;
});
@@ -728,8 +728,8 @@ public class LoanDelinquencyStepDef extends AbstractStepDef {
.as(ErrorMessageHelper.wrongDataInDelinquentLastRepaymentDate(actualLastRepaymentDate, expectedLastRepaymentDate))//
.isEqualTo(expectedLastRepaymentDate);//
log.info("loanDetails.delinquent.lastRepaymentAmount: {}", actualLastRepaymentAmount);
log.info("loanDetails.delinquent.lastRepaymentDate: {}", actualLastRepaymentDate);
log.debug("loanDetails.delinquent.lastRepaymentAmount: {}", actualLastRepaymentAmount);
log.debug("loanDetails.delinquent.lastRepaymentDate: {}", actualLastRepaymentDate);
}
private List<String> fetchValuesOfDelinquencyPausePeriods(List<String> header, GetLoansLoanIdDelinquencyPausePeriod t) {
@@ -757,8 +757,8 @@ public class LoanDelinquencyStepDef extends AbstractStepDef {
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
.isEqualTo(errorMessageExpected);
log.info("ERROR CODE: {}", errorCodeActual);
log.info("ERROR MESSAGE: {}", errorMessageActual);
log.debug("ERROR CODE: {}", errorCodeActual);
log.debug("ERROR MESSAGE: {}", errorMessageActual);
}
@Then("LoanDelinquencyRangeChangeBusinessEvent is created")
@@ -544,7 +544,7 @@ public class LoanRepaymentStepDef extends AbstractStepDef {
.retrieveTransactionTemplate(loanId1, "prepayLoan", DATE_FORMAT, transactionDate, DEFAULT_LOCALE).execute();
Double transactionAmount = response.body().getAmount();
log.info("%n--- Loan Pay-off with amount: {} ---", transactionAmount);
log.debug("%n--- Loan Pay-off with amount: {} ---", transactionAmount);
makeRepayment(DEFAULT_REPAYMENT_TYPE, transactionDate, transactionAmount, null);
}
@@ -572,9 +572,10 @@ public class LoanRepaymentStepDef extends AbstractStepDef {
eventAssertionBuilder
.extractingData(loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getId())
.isEqualTo(targetTransaction.getId());
eventAssertionBuilder.extractingData(
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getAmount().doubleValue())
.isEqualTo(targetTransaction.getAmount());
eventAssertionBuilder
.extractingBigDecimal(
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getAmount())
.isEqualTo(BigDecimal.valueOf(targetTransaction.getAmount()));
eventAssertionBuilder
.extractingData(
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getManuallyReversed())
@@ -587,9 +588,10 @@ public class LoanRepaymentStepDef extends AbstractStepDef {
eventAssertionBuilder
.extractingData(loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getNewTransactionDetail().getId())
.isEqualTo(repaymentAdjustmentResponse.body().getResourceId());
eventAssertionBuilder.extractingData(
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getNewTransactionDetail().getAmount().doubleValue())
.isEqualTo(amountValue);
eventAssertionBuilder
.extractingBigDecimal(
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getNewTransactionDetail().getAmount())
.isEqualTo(BigDecimal.valueOf(amountValue));
eventAssertionBuilder.extractingData(
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getNewTransactionDetail().getExternalOwnerId())
.isEqualTo(externalOwnerId);
@@ -163,7 +163,7 @@ public class LoanRescheduleStepDef extends AbstractStepDef {
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
.isEqualTo(errorMessageExpected);
log.info("ERROR CODE: {}", errorCodeActual);
log.info("ERROR MESSAGE: {}", errorMessageActual);
log.debug("ERROR CODE: {}", errorCodeActual);
log.debug("ERROR MESSAGE: {}", errorMessageActual);
}
}
@@ -44,7 +44,6 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.avro.loan.v1.LoanAccountDataV1;
@@ -386,8 +385,8 @@ public class LoanStepDef extends AbstractStepDef {
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
.isEqualTo(errorMessageExpected);
log.info("ERROR CODE: {}", errorCodeActual);
log.info("ERROR MESSAGE: {}", errorMessageActual);
log.debug("ERROR CODE: {}", errorCodeActual);
log.debug("ERROR MESSAGE: {}", errorMessageActual);
}
@When("Admin creates a fully customized loan with the following data:")
@@ -548,8 +547,8 @@ public class LoanStepDef extends AbstractStepDef {
assertThat(errorCode).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(403);
assertThat(errorMessage).isEqualTo(ErrorMessageHelper.downpaymentDisabledOnProductErrorCodeMsg());
log.info("Error code: {}", errorCode);
log.info("Error message: {}}", errorMessage);
log.debug("Error code: {}", errorCode);
log.debug("Error message: {}}", errorMessage);
}
@When("Admin creates a fully customized loan with auto downpayment {double}% and with the following data:")
@@ -845,8 +844,8 @@ public class LoanStepDef extends AbstractStepDef {
assertThat(errorCodeActual).as(ErrorMessageHelper.wrongErrorCode(errorCodeActual, errorCodeExpected)).isEqualTo(errorCodeExpected);
log.info("ERROR CODE: {}", errorCodeActual);
log.info("ERROR MESSAGE: {}", errorMessageActual);
log.debug("ERROR CODE: {}", errorCodeActual);
log.debug("ERROR MESSAGE: {}", errorMessageActual);
}
@When("Admin creates a fully customized loan with Advanced payment allocation and with product no Advanced payment allocation set results an error:")
@@ -927,8 +926,8 @@ public class LoanStepDef extends AbstractStepDef {
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
.isEqualTo(errorMessageExpected);
log.info("ERROR CODE: {}", errorCodeActual);
log.info("ERROR MESSAGE: {}", errorMessageActual);
log.debug("ERROR CODE: {}", errorCodeActual);
log.debug("ERROR MESSAGE: {}", errorMessageActual);
}
@When("Admin creates a fully customized loan with installment level delinquency and with the following data:")
@@ -1519,7 +1518,7 @@ public class LoanStepDef extends AbstractStepDef {
assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(403);
assertThat(developerMessage).matches(ErrorMessageHelper.disburseMaxAmountFailure());
log.info("Error message: {}", developerMessage);
log.debug("Error message: {}", developerMessage);
}
@Then("Loan has {double} outstanding amount")
@@ -2073,18 +2072,24 @@ public class LoanStepDef extends AbstractStepDef {
@When("Admin checks that Loan COB is running until the current business date")
public void checkLoanCOBCatchUpRunningUntilCOBBusinessDate() {
await().pollInterval(2, TimeUnit.SECONDS).atMost(Duration.ofSeconds(20)).until(() -> {
Response<IsCatchUpRunningResponse> isCatchUpRunningResponse = loanCobCatchUpApi.isCatchUpRunning().execute();
ErrorHelper.checkSuccessfulApiCall(isCatchUpRunningResponse);
IsCatchUpRunningResponse isCatchUpRunning = isCatchUpRunningResponse.body();
return isCatchUpRunning.getIsCatchUpRunning();
});
await().pollInterval(2, TimeUnit.SECONDS).atMost(Duration.ofMinutes(4)).until(() -> {
Response<IsCatchUpRunningResponse> isCatchUpRunningResponse = loanCobCatchUpApi.isCatchUpRunning().execute();
ErrorHelper.checkSuccessfulApiCall(isCatchUpRunningResponse);
IsCatchUpRunningResponse isCatchUpRunning = isCatchUpRunningResponse.body();
return !isCatchUpRunning.getIsCatchUpRunning();
});
await().atMost(Duration.ofMinutes(2)) //
.pollInterval(Duration.ofSeconds(5)) //
.pollDelay(Duration.ofSeconds(5)) //
.until(() -> {
Response<IsCatchUpRunningResponse> isCatchUpRunningResponse = loanCobCatchUpApi.isCatchUpRunning().execute();
ErrorHelper.checkSuccessfulApiCall(isCatchUpRunningResponse);
IsCatchUpRunningResponse isCatchUpRunning = isCatchUpRunningResponse.body();
return isCatchUpRunning.getIsCatchUpRunning();
});
await().atMost(Duration.ofMinutes(4)) //
.pollInterval(Duration.ofSeconds(5)) //
.pollDelay(Duration.ofSeconds(5)) //
.until(() -> {
Response<IsCatchUpRunningResponse> isCatchUpRunningResponse = loanCobCatchUpApi.isCatchUpRunning().execute();
ErrorHelper.checkSuccessfulApiCall(isCatchUpRunningResponse);
IsCatchUpRunningResponse isCatchUpRunning = isCatchUpRunningResponse.body();
return !isCatchUpRunning.getIsCatchUpRunning();
});
}
@Then("Loan's actualMaturityDate is {string}")
@@ -2289,7 +2294,7 @@ public class LoanStepDef extends AbstractStepDef {
String futureInstallmentAllocationRuleNew) throws IOException {
DefaultLoanProduct product = DefaultLoanProduct.valueOf(loanProductName);
Long loanProductId = loanProductResolver.resolve(product);
log.info("loanProductId: {}", loanProductId);
log.debug("loanProductId: {}", loanProductId);
Response<GetLoanProductsProductIdResponse> loanProductDetails = loanProductsApi.retrieveLoanProductDetails(loanProductId).execute();
ErrorHelper.checkSuccessfulApiCall(loanProductDetails);
@@ -2319,7 +2324,7 @@ public class LoanStepDef extends AbstractStepDef {
public void editRepaymentStartDateType(String loanProductName, String repaymentStartDateType) throws IOException {
DefaultLoanProduct product = DefaultLoanProduct.valueOf(loanProductName);
Long loanProductId = loanProductResolver.resolve(product);
log.info("loanProductId: {}", loanProductId);
log.debug("loanProductId: {}", loanProductId);
Map<String, Integer> repaymentStartDateTypeMap = Map.of("DISBURSEMENT_DATE", 1, "SUBMITTED_ON_DATE", 2);
@@ -61,16 +61,16 @@ Feature: LoanAccrualTransaction
And Customer makes "AUTOPAY" repayment on "03 January 2023" with 250 EUR transaction amount
When Admin adds "LOAN_SNOOZE_FEE" due date charge with "04 January 2023" due date and 10 EUR transaction amount
When Admin sets the business date to "04 January 2023"
And Admin runs COB job
And Admin runs inline COB job for Loan
When Admin sets the business date to "05 January 2023"
And Customer makes "AUTOPAY" repayment on "05 January 2023" with 510 EUR transaction amount
Then Loan has 0 outstanding amount
And Admin makes "REPAYMENT_ADJUSTMENT_CHARGEBACK" chargeback with 250 EUR transaction amount for Payment nr. 2
Then Loan has 250 outstanding amount
Then LoanAccrualTransactionCreatedBusinessEvent is raised on "05 January 2023"
Then Loan Transactions tab has a transaction with date: "05 January 2023", and with the following data:
| Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
| Accrual | 10.0 | 0.0 | 0.0 | 10.0 | 0.0 | 0.0 |
Then LoanAccrualTransactionCreatedBusinessEvent is raised on "05 January 2023"
And Admin makes "REPAYMENT_ADJUSTMENT_CHARGEBACK" chargeback with 250 EUR transaction amount for Payment nr. 2
Then Loan has 250 outstanding amount
Scenario: Verify that after periodic accrual transaction job accrual event is raised when loan has a fee-charge added with waive charge and undo waive charge
@@ -322,7 +322,7 @@ Feature: LoanAccrualTransaction
And Admin runs COB job
And Admin successfully disburse the loan on "28 April 2023" with "20" EUR transaction amount
When Admin sets the business date to "29 April 2023"
And Admin runs COB job
And Admin runs inline COB job for Loan
Then Loan Repayment schedule has 1 periods, with the following data for periods:
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 26 April 2023 | | 1000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
@@ -349,7 +349,7 @@ Feature: LoanAccrualTransaction
Then Loan has 1000 outstanding amount
When Admin adds "LOAN_SNOOZE_FEE" due date charge with "1 May 2023" due date and 10 EUR transaction amount
When Admin sets the business date to "2 May 2023"
And Admin runs COB job
And Admin runs inline COB job for Loan
When Admin sets the business date to "8 May 2023"
And Admin successfully disburse the loan on "8 May 2023" with "20" EUR transaction amount
Then Loan Repayment schedule has 1 periods, with the following data for periods:
File diff suppressed because it is too large Load Diff
@@ -1043,7 +1043,7 @@ Feature: LoanChargeback
When Admin sets the business date to "05 April 2023"
When Admin adds "LOAN_SNOOZE_FEE" due date charge with "05 April 2023" due date and 20 EUR transaction amount
Then Loan has 270 outstanding amount
And Admin runs COB job
And Admin runs inline COB job for Loan
And Customer makes "AUTOPAY" repayment on "05 April 2023" with 270 EUR transaction amount
Then Loan has 0 outstanding amount
And Admin makes "REPAYMENT_ADJUSTMENT_CHARGEBACK" chargeback with 250 EUR transaction amount for Payment nr. 2
@@ -3398,6 +3398,8 @@ Feature: LoanRepayment
When Customer undo "1"th "Repayment" transaction made on "24 June 2024"
Then Loan status will be "ACTIVE"
# Needs to fix Merchant issued Refund - Interest refund order
@Skip
Scenario: Verify the relationship for Interest Refund transaction after repayment by reverting related transaction
When Admin sets the business date to "30 January 2024"
When Admin creates a client with random data
@@ -3413,17 +3415,19 @@ Feature: LoanRepayment
| 01 January 2024 | Disbursement | 200.0 | 0.0 | 0.0 | 0.0 | 0.0 | 200.0 | false |
| 15 January 2024 | Merchant Issued Refund | 50.0 | 50.0 | 0.0 | 0.0 | 0.0 | 150.0 | false |
| 15 January 2024 | Interest Refund | 0.29 | 0.29 | 0.0 | 0.0 | 0.0 | 149.71 | false |
| 16 January 2024 | Payout Refund | 50.0 | 50.0 | 0.0 | 0.0 | 0.0 | 99.71 | false |
| 16 January 2024 | Interest Refund | 0.31 | 0.31 | 0.0 | 0.0 | 0.0 | 99.4 | false |
When Customer makes "AUTOPAY" repayment on "10 January 2024" with 25 EUR transaction amount (and transaction fails because of wrong date)
| 16 January 2024 | Payout Refund | 50.0 | 48.79 | 1.21 | 0.0 | 0.0 | 100.92 | false |
| 16 January 2024 | Interest Refund | 0.31 | 0.31 | 0.0 | 0.0 | 0.0 | 100.61 | false |
Then In Loan Transactions the "3"th Transaction has relationship type=RELATED with the "2"th Transaction
Then In Loan Transactions the "5"th Transaction has relationship type=RELATED with the "4"th Transaction
When Customer makes "AUTOPAY" repayment on "10 January 2024" with 25 EUR transaction amount
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted |
| 01 January 2024 | Disbursement | 200.0 | 0.0 | 0.0 | 0.0 | 0.0 | 200.0 | false |
| 10 January 2024 | Repayment | 25.0 | 25.0 | 0.0 | 0.0 | 0.0 | 175.0 | false |
| 15 January 2024 | Merchant Issued Refund | 50.0 | 50.0 | 0.0 | 0.0 | 0.0 | 125.0 | false |
| 15 January 2024 | Interest Refund | 0.29 | 0.29 | 0.0 | 0.0 | 0.0 | 124.71 | false |
| 16 January 2024 | Payout Refund | 50.0 | 50.0 | 0.0 | 0.0 | 0.0 | 74.71 | false |
| 16 January 2024 | Interest Refund | 0.31 | 0.31 | 0.0 | 0.0 | 0.0 | 74.4 | false |
| 15 January 2024 | Merchant Issued Refund | 50.0 | 48.9 | 1.1 | 0.0 | 0.0 | 126.1 | false |
| 15 January 2024 | Interest Refund | 0.29 | 0.29 | 0.0 | 0.0 | 0.0 | 125.81 | false |
| 16 January 2024 | Payout Refund | 50.0 | 49.95 | 0.05 | 0.0 | 0.0 | 75.86 | false |
| 16 January 2024 | Interest Refund | 0.31 | 0.31 | 0.0 | 0.0 | 0.0 | 75.55 | false |
Then In Loan Transactions the "4"th Transaction has relationship type=RELATED with the "3"th Transaction
Then In Loan Transactions the "6"th Transaction has relationship type=RELATED with the "5"th Transaction
When Customer undo "1"th "Merchant Issued Refund" transaction made on "15 January 2024"
@@ -3432,7 +3436,7 @@ Feature: LoanRepayment
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted |
| 01 January 2024 | Disbursement | 200.0 | 0.0 | 0.0 | 0.0 | 0.0 | 200.0 | false |
| 10 January 2024 | Repayment | 25.0 | 25.0 | 0.0 | 0.0 | 0.0 | 175.0 | false |
| 15 January 2024 | Merchant Issued Refund | 50.0 | 50.0 | 0.0 | 0.0 | 0.0 | 125.0 | true |
| 15 January 2024 | Interest Refund | 0.29 | 0.29 | 0.0 | 0.0 | 0.0 | 124.71 | true |
| 16 January 2024 | Payout Refund | 50.0 | 50.0 | 0.0 | 0.0 | 0.0 | 125.0 | true |
| 16 January 2024 | Interest Refund | 0.31 | 0.31 | 0.0 | 0.0 | 0.0 | 124.69 | true |
| 15 January 2024 | Merchant Issued Refund | 50.0 | 48.9 | 1.1 | 0.0 | 0.0 | 126.1 | true |
| 15 January 2024 | Interest Refund | 0.29 | 0.29 | 0.0 | 0.0 | 0.0 | 125.81 | true |
| 16 January 2024 | Payout Refund | 50.0 | 48.83 | 1.17 | 0.0 | 0.0 | 126.17 | true |
| 16 January 2024 | Interest Refund | 0.31 | 0.31 | 0.0 | 0.0 | 0.0 | 125.86 | true |
@@ -253,7 +253,8 @@ public class LoanCOBAccountLockCatchupInlineCOBTest extends BaseLoanIntegrationT
// days behind
loanCOBCatchUpHelper.executeLoanCOBCatchUp();
Awaitility.await().atMost(Duration.ofSeconds(30)).with().pollInterval(Duration.ofSeconds(5)) //
Awaitility.await().atMost(Duration.ofMinutes(2)).with().pollInterval(Duration.ofSeconds(5)) //
.pollDelay(Duration.ofSeconds(5)) //
.until(() -> loanCOBCatchUpHelper.isLoanCOBCatchUpFinishedFor(LocalDate.of(2020, 3, 4))); //
loan = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanID);
@@ -51,7 +51,9 @@ public final class NotificationHelper {
// Waiting for notifications to be available is needed due to the asynchronous event processing
public static void waitUntilNotificationsAreAvailable(final RequestSpecification requestSpec,
final ResponseSpecification responseSpec) {
await().atMost(Duration.ofSeconds(30)).pollInterval(Duration.ofMillis(250))
await().atMost(Duration.ofSeconds(30)) //
.pollInterval(Duration.ofSeconds(5)) //
.pollDelay(Duration.ofSeconds(5)) //
.until(() -> NotificationHelper.areNotificationsAvailable(requestSpec, responseSpec));
}
}
@@ -223,26 +223,29 @@ public class SchedulerJobHelper extends IntegrationTest {
}
private void awaitJob(Instant beforeExecuteTime, Supplier<Callable<Map<String, String>>> retrieveLastRunHistory) {
final Duration timeout = Duration.ofMinutes(4);
final Duration pause = Duration.ofSeconds(2);
final Duration timeout = Duration.ofMinutes(2);
final Duration pause = Duration.ofSeconds(5);
DateTimeFormatter df = DateTimeFormatter.ISO_INSTANT; // FINERACT-926
// Await JobDetailData.lastRunHistory [JobDetailHistoryData]
// jobRunStartTime >= beforeExecuteTime (or timeout)
// jobRunEndTime to be both set and >= jobRunStartTime (or timeout)
Map<String, String> finalLastRunHistory = await().atMost(timeout).pollInterval(pause).until(retrieveLastRunHistory.get(),
lastRunHistory -> {
String jobRunStartText = lastRunHistory.get("jobRunStartTime");
if (jobRunStartText == null) {
return false;
}
String jobRunEndText = lastRunHistory.get("jobRunEndTime");
if (jobRunEndText == null) {
return false;
}
Instant jobRunStartTime = df.parse(jobRunStartText, Instant::from);
Instant jobRunEndTime = df.parse(jobRunEndText, Instant::from);
return !jobRunStartTime.isBefore(beforeExecuteTime) && !jobRunEndTime.isBefore(jobRunStartTime);
});
Map<String, String> finalLastRunHistory = await().atMost(timeout) //
.pollInterval(pause) //
.pollDelay(pause) //
.until(retrieveLastRunHistory.get(), //
lastRunHistory -> {
String jobRunStartText = lastRunHistory.get("jobRunStartTime");
if (jobRunStartText == null) {
return false;
}
String jobRunEndText = lastRunHistory.get("jobRunEndTime");
if (jobRunEndText == null) {
return false;
}
Instant jobRunStartTime = df.parse(jobRunStartText, Instant::from);
Instant jobRunEndTime = df.parse(jobRunEndText, Instant::from);
return !jobRunStartTime.isBefore(beforeExecuteTime) && !jobRunEndTime.isBefore(jobRunStartTime);
});
// Verify triggerType
MatcherAssert.assertThat(finalLastRunHistory.get("triggerType"), is("application"));