FINERACT-2070: Further test cases
This commit is contained in:
committed by
Arnold Gálovics
parent
7c618a69d5
commit
ed5098b5a5
+75
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.service;
|
||||
|
||||
import static org.awaitility.Awaitility.await;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.fineract.client.models.ExecuteJobRequest;
|
||||
import org.apache.fineract.client.models.GetJobsResponse;
|
||||
import org.apache.fineract.client.services.SchedulerJobApi;
|
||||
import org.apache.fineract.test.data.job.Job;
|
||||
import org.apache.fineract.test.data.job.JobResolver;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import retrofit2.Response;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class JobService {
|
||||
|
||||
@Autowired
|
||||
private SchedulerJobApi schedulerJobApi;
|
||||
|
||||
private final JobResolver jobResolver;
|
||||
|
||||
public void execute(Job job) {
|
||||
try {
|
||||
Long jobId = jobResolver.resolve(job);
|
||||
Response<Void> response = schedulerJobApi.executeJob(jobId, "executeJob", new ExecuteJobRequest()).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Exception while executing job %s".formatted(job.getName()), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void executeAndWait(Job job) {
|
||||
execute(job);
|
||||
waitUntilJobIsFinished(job);
|
||||
}
|
||||
|
||||
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))
|
||||
.until(() -> {
|
||||
log.info("Waiting for job {} to finish", jobName);
|
||||
Long jobId = jobResolver.resolve(job);
|
||||
Response<GetJobsResponse> getJobsResponse = schedulerJobApi.retrieveOne5(jobId).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(getJobsResponse);
|
||||
Boolean currentlyRunning = getJobsResponse.body().getCurrentlyRunning();
|
||||
return BooleanUtils.isFalse(currentlyRunning);
|
||||
});
|
||||
}
|
||||
}
|
||||
+771
@@ -0,0 +1,771 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.assetexternalization;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.cucumber.datatable.DataTable;
|
||||
import io.cucumber.java.en.Then;
|
||||
import io.cucumber.java.en.When;
|
||||
import java.io.IOException;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.client.models.ExternalOwnerJournalEntryData;
|
||||
import org.apache.fineract.client.models.ExternalOwnerTransferJournalEntryData;
|
||||
import org.apache.fineract.client.models.ExternalTransferData;
|
||||
import org.apache.fineract.client.models.JournalEntryData;
|
||||
import org.apache.fineract.client.models.PageExternalTransferData;
|
||||
import org.apache.fineract.client.models.PostInitiateTransferRequest;
|
||||
import org.apache.fineract.client.models.PostInitiateTransferResponse;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.services.ExternalAssetOwnersApi;
|
||||
import org.apache.fineract.client.util.JSON;
|
||||
import org.apache.fineract.test.data.AssetExternalizationErrorMessage;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.helper.ErrorMessageHelper;
|
||||
import org.apache.fineract.test.helper.ErrorResponse;
|
||||
import org.apache.fineract.test.helper.Utils;
|
||||
import org.apache.fineract.test.messaging.event.EventCheckHelper;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.apache.fineract.test.support.TestContextKey;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import retrofit2.Response;
|
||||
|
||||
@Slf4j
|
||||
public class AssetExternalizationStepDef extends AbstractStepDef {
|
||||
|
||||
public static final String OWNER_EXTERNAL_ID_PREFIX = "TestOwner-";
|
||||
public static final String DATE_FORMAT_ASSET_EXT = "yyyy-MM-dd";
|
||||
public static final String DEFAULT_LOCALE = "en";
|
||||
public static final String TRANSACTION_TYPE_SALE = "sale";
|
||||
public static final String TRANSACTION_TYPE_BUYBACK = "buyback";
|
||||
public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(DATE_FORMAT_ASSET_EXT);
|
||||
private static final Gson GSON = new JSON().getGson();
|
||||
|
||||
@Autowired
|
||||
private ExternalAssetOwnersApi externalAssetOwnersApi;
|
||||
|
||||
@Autowired
|
||||
private EventCheckHelper eventCheckHelper;
|
||||
|
||||
@When("Admin makes asset externalization request by Loan ID with unique ownerExternalId, user-generated transferExternalId and the following data:")
|
||||
public void createAssetExternalizationRequestByLoanIdUserGeneratedExtId(DataTable table) throws IOException {
|
||||
// if user created transferExternalId previously, it will use that, otherwise create a new one
|
||||
String transferExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_TRANSFER_EXTERNAL_ID_USER_GENERATED);
|
||||
if (transferExternalId == null) {
|
||||
transferExternalId = Utils.randomNameGenerator("TestTransferExtId_", 3);
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_TRANSFER_EXTERNAL_ID_USER_GENERATED, transferExternalId);
|
||||
}
|
||||
|
||||
createAssetExternalizationRequestByLoanId(table, transferExternalId);
|
||||
}
|
||||
|
||||
@When("Admin makes asset externalization request by Loan ID with unique ownerExternalId, system-generated transferExternalId and the following data:")
|
||||
public void createAssetExternalizationRequestByLoanIdSystemGeneratedExtId(DataTable table) throws IOException {
|
||||
createAssetExternalizationRequestByLoanId(table, null);
|
||||
}
|
||||
|
||||
private void createAssetExternalizationRequestByLoanId(DataTable table, String transferExternalId) throws IOException {
|
||||
createAssetExternalizationRequestByLoanId(table, transferExternalId, true);
|
||||
}
|
||||
|
||||
private void createAssetExternalizationRequestByLoanId(DataTable table, String transferExternalId, boolean regenerateOwner)
|
||||
throws IOException {
|
||||
List<List<String>> data = table.asLists();
|
||||
List<String> transferData = data.get(1);
|
||||
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostInitiateTransferRequest request = new PostInitiateTransferRequest();
|
||||
if (transferData.get(0).equals(TRANSACTION_TYPE_BUYBACK)) {
|
||||
request.settlementDate(transferData.get(1))//
|
||||
.transferExternalId(transferExternalId)//
|
||||
.dateFormat(DATE_FORMAT_ASSET_EXT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostInitiateTransferResponse> response = externalAssetOwnersApi
|
||||
.transferRequestWithLoanId(loanId, request, transferData.get(0)).execute();
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_RESPONSE, response);
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_BUYBACK_TRANSFER_EXTERNAL_ID_FROM_RESPONSE,
|
||||
response.body().getResourceExternalId());
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
} else if (transferData.get(0).equals(TRANSACTION_TYPE_SALE)) {
|
||||
String ownerExternalId;
|
||||
if (regenerateOwner) {
|
||||
ownerExternalId = Utils.randomNameGenerator(OWNER_EXTERNAL_ID_PREFIX, 3);
|
||||
} else {
|
||||
ownerExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_OWNER_EXTERNAL_ID);
|
||||
}
|
||||
|
||||
request.settlementDate(transferData.get(1))//
|
||||
.ownerExternalId(ownerExternalId)//
|
||||
.transferExternalId(transferExternalId)//
|
||||
.purchasePriceRatio(transferData.get(2))//
|
||||
.dateFormat(DATE_FORMAT_ASSET_EXT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostInitiateTransferResponse> response = externalAssetOwnersApi
|
||||
.transferRequestWithLoanId(loanId, request, transferData.get(0)).execute();
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_RESPONSE, response);
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_SALES_TRANSFER_EXTERNAL_ID_FROM_RESPONSE,
|
||||
response.body().getResourceExternalId());
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_OWNER_EXTERNAL_ID, ownerExternalId);
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
} else {
|
||||
throw new IllegalStateException(String.format("%s is not supported Asset externalization transaction", transferData.get(0)));
|
||||
}
|
||||
}
|
||||
|
||||
@When("Admin makes asset externalization BUYBACK request with ownerExternalId = null and settlement date {string} by Loan ID with system-generated transferExternalId")
|
||||
public void createAssetExternalizationBuybackRequestOwnerNullByLoanIdSystemGeneratedExtId(String settlementDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostInitiateTransferRequest request = new PostInitiateTransferRequest()//
|
||||
.settlementDate(settlementDate)//
|
||||
.ownerExternalId(null)//
|
||||
.transferExternalId(testContext().get(TestContextKey.ASSET_EXTERNALIZATION_TRANSFER_EXTERNAL_ID_FROM_RESPONSE))//
|
||||
.dateFormat(DATE_FORMAT_ASSET_EXT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostInitiateTransferResponse> response = externalAssetOwnersApi
|
||||
.transferRequestWithLoanId(loanId, request, TRANSACTION_TYPE_BUYBACK).execute();
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_RESPONSE, response);
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_BUYBACK_TRANSFER_EXTERNAL_ID_FROM_RESPONSE,
|
||||
response.body().getResourceExternalId());
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
}
|
||||
|
||||
@When("Admin makes asset externalization request by Loan external ID with unique ownerExternalId, user-generated transferExternalId and the following data:")
|
||||
public void createAssetExternalizationRequestByLoanExternalIdUserGeneratedExtId(DataTable table) throws IOException {
|
||||
// if user created transferExternalId previously, it will use that, otherwise create a new one
|
||||
String transferExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_TRANSFER_EXTERNAL_ID_USER_GENERATED);
|
||||
if (transferExternalId == null) {
|
||||
transferExternalId = Utils.randomNameGenerator("TestTransferExtId_", 3);
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_TRANSFER_EXTERNAL_ID_USER_GENERATED, transferExternalId);
|
||||
}
|
||||
|
||||
createAssetExternalizationRequestByLoanExternalId(table, transferExternalId);
|
||||
}
|
||||
|
||||
@When("Admin makes asset externalization request by Loan external ID with unique ownerExternalId, system-generated transferExternalId and the following data:")
|
||||
public void createAssetExternalizationRequestByLoanExternalIdSystemGeneratedExtId(DataTable table) throws IOException {
|
||||
createAssetExternalizationRequestByLoanExternalId(table, null);
|
||||
}
|
||||
|
||||
private void createAssetExternalizationRequestByLoanExternalId(DataTable table, String transferExternalId) throws IOException {
|
||||
List<List<String>> data = table.asLists();
|
||||
List<String> transferData = data.get(1);
|
||||
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
String loanExternalId = loanResponse.body().getResourceExternalId();
|
||||
|
||||
PostInitiateTransferRequest request = new PostInitiateTransferRequest();
|
||||
if (transferData.get(0).equals(TRANSACTION_TYPE_BUYBACK)) {
|
||||
request.settlementDate(transferData.get(1))//
|
||||
.transferExternalId(transferExternalId)//
|
||||
.dateFormat(DATE_FORMAT_ASSET_EXT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostInitiateTransferResponse> response = externalAssetOwnersApi
|
||||
.transferRequestWithLoanExternalId(loanExternalId, request, transferData.get(0)).execute();
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_RESPONSE, response);
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_BUYBACK_TRANSFER_EXTERNAL_ID_FROM_RESPONSE,
|
||||
response.body().getResourceExternalId());
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
} else if (transferData.get(0).equals(TRANSACTION_TYPE_SALE)) {
|
||||
String ownerExternalId = Utils.randomNameGenerator(OWNER_EXTERNAL_ID_PREFIX, 3);
|
||||
|
||||
request.settlementDate(transferData.get(1))//
|
||||
.ownerExternalId(ownerExternalId)//
|
||||
.transferExternalId(transferExternalId)//
|
||||
.purchasePriceRatio(transferData.get(2))//
|
||||
.dateFormat(DATE_FORMAT_ASSET_EXT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostInitiateTransferResponse> response = externalAssetOwnersApi
|
||||
.transferRequestWithLoanExternalId(loanExternalId, request, transferData.get(0)).execute();
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_RESPONSE, response);
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_SALES_TRANSFER_EXTERNAL_ID_FROM_RESPONSE,
|
||||
response.body().getResourceExternalId());
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_OWNER_EXTERNAL_ID, ownerExternalId);
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
} else {
|
||||
throw new IllegalStateException(String.format("%s is not supported Asset externalization transaction", transferData.get(0)));
|
||||
}
|
||||
}
|
||||
|
||||
@Then("Asset externalization response has the correct Loan ID, transferExternalId")
|
||||
public void checkAssetExternalizationResponse() {
|
||||
String ownerExternalIdStored = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_OWNER_EXTERNAL_ID);
|
||||
|
||||
String transferExternalIdExpected = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_TRANSFER_EXTERNAL_ID_USER_GENERATED);
|
||||
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<PostInitiateTransferResponse> response = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_RESPONSE);
|
||||
PostInitiateTransferResponse body = response.body();
|
||||
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);
|
||||
|
||||
assertThat(loanIdActual).as(ErrorMessageHelper.wrongDataInAssetExternalizationResponse(loanIdActual, loanId)).isEqualTo(loanId);
|
||||
assertThat(body.getResourceId()).isNotNull();
|
||||
if (transferExternalIdExpected != null) {
|
||||
assertThat(transferExternalIdActual)
|
||||
.as(ErrorMessageHelper.wrongDataInAssetExternalizationResponse(transferExternalIdActual, transferExternalIdExpected))
|
||||
.isEqualTo(transferExternalIdExpected);
|
||||
} else {
|
||||
assertThat(transferExternalIdActual).isNotEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@Then("Fetching Asset externalization details by loan id gives numberOfElements: {int} with correct ownerExternalId and the following data:")
|
||||
public void checkAssetExternalizationDetailsByLoanId(int numberOfElements, DataTable table) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<PageExternalTransferData> response = externalAssetOwnersApi.getTransfers(null, loanId, null, null, null).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
checkExternalAssetDetails(loanId, null, response, numberOfElements, table);
|
||||
}
|
||||
|
||||
@Then("Fetching Asset externalization details by loan external id gives numberOfElements: {int} with correct ownerExternalId and the following data:")
|
||||
public void checkAssetExternalizationDetailsByLoanExternalId(int numberOfElements, DataTable table) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
String loanExternalId = loanResponse.body().getResourceExternalId();
|
||||
|
||||
Response<PageExternalTransferData> response = externalAssetOwnersApi.getTransfers(null, null, loanExternalId, null, null).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
checkExternalAssetDetails(null, loanExternalId, response, numberOfElements, table);
|
||||
}
|
||||
|
||||
@Then("Fetching Asset externalization details by transfer external id gives numberOfElements: {int} with correct ownerExternalId and the following data:")
|
||||
public void checkAssetExternalizationDetailsByTransferExternalId(int numberOfElements, DataTable table) throws IOException {
|
||||
String transferExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_SALES_TRANSFER_EXTERNAL_ID_FROM_RESPONSE);
|
||||
|
||||
Response<PageExternalTransferData> response = externalAssetOwnersApi.getTransfers(transferExternalId, null, null, null, null)
|
||||
.execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
checkExternalAssetDetails(null, null, response, numberOfElements, table);
|
||||
}
|
||||
|
||||
@Then("Asset externalization details has the generated transferExternalId")
|
||||
public void checkGeneratedTransferExternalId() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<PostInitiateTransferResponse> assetExtResponse = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_RESPONSE);
|
||||
String transferExternalIdExpected = assetExtResponse.body().getResourceExternalId();
|
||||
|
||||
Response<PageExternalTransferData> response = externalAssetOwnersApi.getTransfers(null, loanId, null, null, null).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
List<ExternalTransferData> content = response.body().getContent();
|
||||
|
||||
content.forEach(e -> {
|
||||
assertThat(e.getTransferExternalId()).as(ErrorMessageHelper
|
||||
.wrongDataInAssetExternalizationTransferExternalId(e.getTransferExternalId(), transferExternalIdExpected))
|
||||
.isEqualTo(transferExternalIdExpected);
|
||||
});
|
||||
}
|
||||
|
||||
private void checkExternalAssetDetails(Long loanId, String loanExternalId, Response<PageExternalTransferData> response,
|
||||
int numberOfElements, DataTable table) {
|
||||
PageExternalTransferData body = response.body();
|
||||
Integer numberOfElementsActual = body.getNumberOfElements();
|
||||
List<ExternalTransferData> content = body.getContent();
|
||||
|
||||
String ownerExternalIdStored = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_OWNER_EXTERNAL_ID);
|
||||
String transferExternalId;
|
||||
|
||||
List<List<String>> data = table.asLists();
|
||||
for (int i = 1; i < data.size(); i++) {
|
||||
List<String> expectedValues = data.get(i);
|
||||
|
||||
String transactionType = expectedValues.get(5);
|
||||
if (transactionType.equals(ExternalTransferData.StatusEnum.BUYBACK.getValue())) {
|
||||
transferExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_BUYBACK_TRANSFER_EXTERNAL_ID_FROM_RESPONSE);
|
||||
} else {
|
||||
transferExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_SALES_TRANSFER_EXTERNAL_ID_FROM_RESPONSE);
|
||||
}
|
||||
|
||||
expectedValues.add(ownerExternalIdStored);
|
||||
expectedValues.add(loanId == null ? null : String.valueOf(loanId));
|
||||
expectedValues.add(loanExternalId);
|
||||
expectedValues.add(transferExternalId);
|
||||
|
||||
List<List<String>> actualValuesList = content.stream().map(t -> {
|
||||
List<String> actualValues = new ArrayList<>();
|
||||
actualValues.add(t.getSettlementDate() == null ? null : FORMATTER.format(t.getSettlementDate()));
|
||||
actualValues.add(t.getPurchasePriceRatio() == null ? null : t.getPurchasePriceRatio());
|
||||
actualValues.add(t.getStatus() == null ? null : String.valueOf(t.getStatus()));
|
||||
actualValues.add(t.getEffectiveFrom() == null ? null : FORMATTER.format(t.getEffectiveFrom()));
|
||||
actualValues.add(t.getEffectiveTo() == null ? null : FORMATTER.format(t.getEffectiveTo()));
|
||||
actualValues.add(transactionType);
|
||||
actualValues.add(t.getOwner().getExternalId() == null ? null : t.getOwner().getExternalId());
|
||||
actualValues.add(loanId == null ? null : String.valueOf(t.getLoan().getLoanId()));
|
||||
actualValues.add(loanExternalId == null ? null : t.getLoan().getExternalId());
|
||||
actualValues.add(t.getTransferExternalId());
|
||||
return actualValues;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
boolean containsExpectedValues = actualValuesList.stream().anyMatch(actualValues -> actualValues.equals(expectedValues));
|
||||
|
||||
assertThat(numberOfElementsActual)
|
||||
.as(ErrorMessageHelper.wrongTotalFilteredRecordsInAssetExternalizationDetails(numberOfElementsActual, numberOfElements))
|
||||
.isEqualTo(numberOfElements);
|
||||
assertThat(containsExpectedValues).as(ErrorMessageHelper.wrongValueInExternalAssetDetails(i, actualValuesList, expectedValues))
|
||||
.isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Then("BUYBACK transaction results a {int} error and proper error message when its settlementDate is earlier than the original settlementDate")
|
||||
public void buybackDateError(int errorCodeExpected, DataTable table) throws IOException {
|
||||
List<List<String>> data = table.asLists();
|
||||
List<String> transferData = data.get(1);
|
||||
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
String transferExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_TRANSFER_EXTERNAL_ID_FROM_RESPONSE);
|
||||
|
||||
PostInitiateTransferRequest request = new PostInitiateTransferRequest()//
|
||||
.settlementDate(transferData.get(1))//
|
||||
.transferExternalId(transferExternalId)//
|
||||
.dateFormat(DATE_FORMAT_ASSET_EXT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostInitiateTransferResponse> response = externalAssetOwnersApi
|
||||
.transferRequestWithLoanId(loanId, request, transferData.get(0)).execute();
|
||||
|
||||
PageExternalTransferData transfers = externalAssetOwnersApi.getTransfers(null, loanId, null, null, null).execute().body();
|
||||
String settlementDateOriginal = FORMATTER.format(transfers.getContent().get(0).getSettlementDate());
|
||||
String errorMessageExpected = String.format(
|
||||
"This loan cannot be bought back, settlement date is earlier than effective transfer settlement date: %s",
|
||||
settlementDateOriginal);
|
||||
|
||||
String errorToString = response.errorBody().string();
|
||||
ErrorResponse errorResponse = GSON.fromJson(errorToString, ErrorResponse.class);
|
||||
String errorMessageActual = errorResponse.getDeveloperMessage();
|
||||
int errorCodeActual = response.code();
|
||||
|
||||
assertThat(errorCodeActual).as(ErrorMessageHelper.wrongErrorCode(errorCodeActual, errorCodeExpected)).isEqualTo(errorCodeExpected);
|
||||
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
|
||||
.isEqualTo(errorMessageExpected);
|
||||
|
||||
log.info("ERROR CODE: {}", errorCodeActual);
|
||||
log.info("ERROR MESSAGE: {}", errorMessageActual);
|
||||
}
|
||||
|
||||
@Then("Asset externalization transaction with the following data results a {int} error and {string} error message")
|
||||
public void transactionError(int errorCodeExpected, String errorMessageType, DataTable table) throws IOException {
|
||||
List<List<String>> data = table.asLists();
|
||||
List<String> transferData = data.get(1);
|
||||
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostInitiateTransferRequest request = new PostInitiateTransferRequest();
|
||||
if (transferData.get(0).equals(TRANSACTION_TYPE_BUYBACK)) {
|
||||
request.settlementDate(transferData.get(1))//
|
||||
.transferExternalId(null)//
|
||||
.dateFormat(DATE_FORMAT_ASSET_EXT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
} else if (transferData.get(0).equals(TRANSACTION_TYPE_SALE)) {
|
||||
String ownerExternalId = Utils.randomNameGenerator(OWNER_EXTERNAL_ID_PREFIX, 3);
|
||||
|
||||
request.settlementDate(transferData.get(1))//
|
||||
.ownerExternalId(ownerExternalId)//
|
||||
.transferExternalId(null)//
|
||||
.purchasePriceRatio(transferData.get(2))//
|
||||
.dateFormat(DATE_FORMAT_ASSET_EXT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_OWNER_EXTERNAL_ID, ownerExternalId);
|
||||
} else {
|
||||
throw new IllegalStateException(String.format("%s is not supported Asset externalization transaction", transferData.get(0)));
|
||||
}
|
||||
|
||||
Response<PostInitiateTransferResponse> response = externalAssetOwnersApi
|
||||
.transferRequestWithLoanId(loanId, request, transferData.get(0)).execute();
|
||||
|
||||
AssetExternalizationErrorMessage errorMsgType = AssetExternalizationErrorMessage.valueOf(errorMessageType);
|
||||
String errorMessageExpected = errorMsgType.getValue();
|
||||
|
||||
String errorToString = response.errorBody().string();
|
||||
ErrorResponse errorResponse = GSON.fromJson(errorToString, ErrorResponse.class);
|
||||
String errorMessageActual = errorResponse.getDeveloperMessage();
|
||||
int errorCodeActual = response.code();
|
||||
|
||||
assertThat(errorCodeActual).as(ErrorMessageHelper.wrongErrorCode(errorCodeActual, errorCodeExpected)).isEqualTo(errorCodeExpected);
|
||||
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
|
||||
.isEqualTo(errorMessageExpected);
|
||||
|
||||
log.info("ERROR CODE: {}", errorCodeActual);
|
||||
log.info("ERROR MESSAGE: {}", errorMessageActual);
|
||||
}
|
||||
|
||||
@Then("Asset externalization SALES transaction with ownerExternalId = null and the following data results a {int} error and {string} error message")
|
||||
public void transactionErrorSalesOwnerNull(int errorCodeExpected, String errorMessageType, DataTable table) throws IOException {
|
||||
List<List<String>> data = table.asLists();
|
||||
List<String> transferData = data.get(1);
|
||||
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostInitiateTransferRequest request = new PostInitiateTransferRequest()//
|
||||
.settlementDate(transferData.get(0))//
|
||||
.ownerExternalId(null)//
|
||||
.transferExternalId(null)//
|
||||
.purchasePriceRatio(transferData.get(1))//
|
||||
.dateFormat(DATE_FORMAT_ASSET_EXT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostInitiateTransferResponse> response = externalAssetOwnersApi
|
||||
.transferRequestWithLoanId(loanId, request, TRANSACTION_TYPE_SALE).execute();
|
||||
|
||||
AssetExternalizationErrorMessage errorMsgType = AssetExternalizationErrorMessage.valueOf(errorMessageType);
|
||||
String errorMessageExpected = errorMsgType.getValue();
|
||||
|
||||
String errorToString = response.errorBody().string();
|
||||
ErrorResponse errorResponse = GSON.fromJson(errorToString, ErrorResponse.class);
|
||||
String errorMessageActual = errorResponse.getDeveloperMessage();
|
||||
int errorCodeActual = response.code();
|
||||
|
||||
assertThat(errorCodeActual).as(ErrorMessageHelper.wrongErrorCode(errorCodeActual, errorCodeExpected)).isEqualTo(errorCodeExpected);
|
||||
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
|
||||
.isEqualTo(errorMessageExpected);
|
||||
|
||||
log.info("ERROR CODE: {}", errorCodeActual);
|
||||
log.info("ERROR MESSAGE: {}", errorMessageActual);
|
||||
}
|
||||
|
||||
@Then("The latest asset externalization transaction with {string} status has the following TRANSFER Journal entries:")
|
||||
public void checkJournalEntriesTransaction(String status, DataTable table) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Long lastTransferIdByStatus = getLastTransferIdByStatus(loanId, status);
|
||||
|
||||
Response<ExternalOwnerTransferJournalEntryData> journalEntriesOfTransfer = externalAssetOwnersApi
|
||||
.getJournalEntriesOfTransfer(lastTransferIdByStatus, null, null).execute();
|
||||
List<JournalEntryData> content = journalEntriesOfTransfer.body().getJournalEntryData().getContent();
|
||||
|
||||
List<List<String>> data = table.asLists();
|
||||
int linesExpected = data.size() - 1;
|
||||
|
||||
for (int i = 1; i < data.size(); i++) {
|
||||
List<String> expectedValues = data.get(i);
|
||||
List<List<String>> actualValuesList = content.stream().map(t -> {
|
||||
List<String> actualValues = new ArrayList<>();
|
||||
actualValues.add(t.getGlAccountType().getValue());
|
||||
actualValues.add(t.getGlAccountCode());
|
||||
actualValues.add(t.getGlAccountName());
|
||||
actualValues.add(t.getEntryType().getValue());
|
||||
actualValues.add(t.getAmount().setScale(2, RoundingMode.HALF_DOWN).toString());
|
||||
return actualValues;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
boolean containsExpectedValues = actualValuesList.stream().anyMatch(actualValues -> actualValues.equals(expectedValues));
|
||||
assertThat(containsExpectedValues)
|
||||
.as(ErrorMessageHelper.wrongValueInLineInAssetExternalizationJournalEntry(i, actualValuesList, expectedValues))
|
||||
.isTrue();
|
||||
|
||||
int linesActual = journalEntriesOfTransfer.body().getJournalEntryData().getNumberOfElements();
|
||||
assertThat(linesActual).as(ErrorMessageHelper.wrongNumberOfLinesInAssetExternalizationJournalEntry(linesActual, linesExpected))
|
||||
.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());
|
||||
}
|
||||
|
||||
private Long getLastTransferIdByStatus(Long loanId, String status) throws IOException {
|
||||
Response<PageExternalTransferData> transfersResponse = externalAssetOwnersApi.getTransfers(null, loanId, null, null, null)
|
||||
.execute();
|
||||
List<ExternalTransferData> content = transfersResponse.body().getContent();
|
||||
|
||||
ExternalTransferData result = content.stream().filter(t -> status.equals(t.getStatus().getValue()))
|
||||
.reduce((first, second) -> second)
|
||||
.orElseThrow(() -> new IllegalStateException(String.format("No Journal entry found with status: %s", status)));
|
||||
|
||||
return result.getTransferId();
|
||||
}
|
||||
|
||||
private Long getLastTransferId(Long loanId) throws IOException {
|
||||
Response<PageExternalTransferData> transfersResponse = externalAssetOwnersApi.getTransfers(null, loanId, null, null, null)
|
||||
.execute();
|
||||
List<ExternalTransferData> content = transfersResponse.body().getContent();
|
||||
ExternalTransferData result = content.stream().reduce((first, second) -> second)
|
||||
.orElseThrow(() -> new IllegalStateException("transfersResponse.body().getContent() is empty"));
|
||||
|
||||
return result.getTransferId();
|
||||
}
|
||||
|
||||
@Then("The asset external owner has the following OWNER Journal entries:")
|
||||
public void checkJournalEntriesOwner(DataTable table) throws IOException {
|
||||
String ownerExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_OWNER_EXTERNAL_ID);
|
||||
|
||||
Response<ExternalOwnerJournalEntryData> journalEntriesOfOwner = externalAssetOwnersApi
|
||||
.getJournalEntriesOfOwner(ownerExternalId, null, null).execute();
|
||||
List<JournalEntryData> content = journalEntriesOfOwner.body().getJournalEntryData().getContent();
|
||||
|
||||
List<List<String>> data = table.asLists();
|
||||
int linesExpected = data.size() - 1;
|
||||
|
||||
for (int i = 1; i < data.size(); i++) {
|
||||
List<String> expectedValues = data.get(i);
|
||||
List<List<String>> actualValuesList = content.stream().map(t -> {
|
||||
List<String> actualValues = new ArrayList<>();
|
||||
actualValues.add(t.getGlAccountType().getValue());
|
||||
actualValues.add(t.getGlAccountCode());
|
||||
actualValues.add(t.getGlAccountName());
|
||||
actualValues.add(t.getEntryType().getValue());
|
||||
actualValues.add(t.getAmount().setScale(2, RoundingMode.HALF_DOWN).toString());
|
||||
return actualValues;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
boolean containsExpectedValues = actualValuesList.stream().anyMatch(actualValues -> actualValues.equals(expectedValues));
|
||||
assertThat(containsExpectedValues)
|
||||
.as(ErrorMessageHelper.wrongValueInLineInAssetExternalizationJournalEntry(i, actualValuesList, expectedValues))
|
||||
.isTrue();
|
||||
|
||||
int linesActual = journalEntriesOfOwner.body().getJournalEntryData().getNumberOfElements();
|
||||
assertThat(linesActual).as(ErrorMessageHelper.wrongNumberOfLinesInAssetExternalizationJournalEntry(linesActual, linesExpected))
|
||||
.isEqualTo(linesExpected);
|
||||
}
|
||||
|
||||
log.info("ownerExternalId: {}", journalEntriesOfOwner.body().getOwnerData().getExternalId());
|
||||
}
|
||||
|
||||
@Then("LoanOwnershipTransferBusinessEvent is created")
|
||||
public void loanOwnershipTransferBusinessEventCheck() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
Long transferId = getLastTransferId(loanId);
|
||||
|
||||
eventCheckHelper.loanOwnershipTransferBusinessEventCheck(loanId, transferId);
|
||||
}
|
||||
|
||||
@Then("LoanOwnershipTransferBusinessEvent with transfer status: {string} and transfer status reason {string} is created")
|
||||
public void loanOwnershipTransferBusinessEventCheck(String transferStatus, String transferStatusReason) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
Long transferId = getLastTransferId(loanId);
|
||||
|
||||
eventCheckHelper.loanOwnershipTransferBusinessEventWithStatusCheck(loanId, transferId, transferStatus, transferStatusReason);
|
||||
}
|
||||
|
||||
@Then("LoanAccountSnapshotBusinessEvent is created")
|
||||
public void loanAccountSnapshotBusinessEventCheck() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
Long transferId = getLastTransferId(loanId);
|
||||
|
||||
eventCheckHelper.loanAccountSnapshotBusinessEventCheck(loanId, transferId);
|
||||
}
|
||||
|
||||
@Then("Asset externalization response {string} has the correct Loan ID, transferExternalId")
|
||||
public void checkAssetExternalizationResponse(String type) {
|
||||
String ownerExternalIdStored = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_OWNER_EXTERNAL_ID);
|
||||
|
||||
String transferExternalIdExpected = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_BUYBACK_TRANSFER_PREFIX + "_" + type);
|
||||
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<PostInitiateTransferResponse> response = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_RESPONSE);
|
||||
PostInitiateTransferResponse body = response.body();
|
||||
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);
|
||||
|
||||
assertThat(loanIdActual).as(ErrorMessageHelper.wrongDataInAssetExternalizationResponse(loanIdActual, loanId)).isEqualTo(loanId);
|
||||
assertThat(body.getResourceId()).isNotNull();
|
||||
if (transferExternalIdExpected != null) {
|
||||
assertThat(transferExternalIdActual)
|
||||
.as(ErrorMessageHelper.wrongDataInAssetExternalizationResponse(transferExternalIdActual, transferExternalIdExpected))
|
||||
.isEqualTo(transferExternalIdExpected);
|
||||
} else {
|
||||
assertThat(transferExternalIdActual).isNotEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@When("Admin makes asset externalization request for type {string} by Loan ID with unique ownerExternalId, user-generated transferExternalId and the following data:")
|
||||
public void createAssetExternalizationRequestByLoanIdUserGeneratedExtId(String type, DataTable table) throws IOException {
|
||||
// if user created transferExternalId previously, it will use that, otherwise create a new one
|
||||
String transferExternalId = testContext()
|
||||
.get(TestContextKey.ASSET_EXTERNALIZATION_TRANSFER_EXTERNAL_ID_USER_GENERATED + "_" + type);
|
||||
if (transferExternalId == null) {
|
||||
transferExternalId = Utils.randomNameGenerator("TestTransferExtId_", 3);
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_TRANSFER_EXTERNAL_ID_USER_GENERATED + "_" + type, transferExternalId);
|
||||
}
|
||||
|
||||
createAssetExternalizationRequestByLoanId(table, transferExternalId);
|
||||
}
|
||||
|
||||
@When("Admin send {string} command to the transaction type {string}")
|
||||
public void adminTransactionCommandTheWithType(String command, String type) throws IOException {
|
||||
String transferExternalId = testContext()
|
||||
.get(TestContextKey.ASSET_EXTERNALIZATION_TRANSFER_EXTERNAL_ID_USER_GENERATED + "_" + type);
|
||||
Response<PostInitiateTransferResponse> response = externalAssetOwnersApi.transferRequestWithId1(transferExternalId, command)
|
||||
.execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
}
|
||||
|
||||
@When("Admin send {string} command to the transaction type {string} will throw error")
|
||||
public void adminTransactionCommandTheWithTypeThrowError(String command, String type) throws IOException {
|
||||
String transferExternalId = testContext()
|
||||
.get(TestContextKey.ASSET_EXTERNALIZATION_TRANSFER_EXTERNAL_ID_USER_GENERATED + "_" + type);
|
||||
Response<PostInitiateTransferResponse> response = externalAssetOwnersApi.transferRequestWithId1(transferExternalId, command)
|
||||
.execute();
|
||||
ErrorHelper.checkFailedApiCall(response, 403);
|
||||
}
|
||||
|
||||
@Then("Fetching Asset externalization details by loan id gives numberOfElements: {int} with correct ownerExternalId, ignore transactionExternalId and contain the following data:")
|
||||
public void checkAssetExternalizationDetailsByLoanIdIgnoreTransactionExternalId(int numberOfElements, DataTable table)
|
||||
throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<PageExternalTransferData> response = externalAssetOwnersApi.getTransfers(null, loanId, null, null, null).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
checkExternalAssetDetailsIgnoreTransferExternalId(loanId, null, response, numberOfElements, table);
|
||||
}
|
||||
|
||||
private void checkExternalAssetDetailsIgnoreTransferExternalId(Long loanId, String loanExternalId,
|
||||
Response<PageExternalTransferData> response, int numberOfElements, DataTable table) {
|
||||
PageExternalTransferData body = response.body();
|
||||
Integer numberOfElementsActual = body.getNumberOfElements();
|
||||
List<ExternalTransferData> content = body.getContent();
|
||||
|
||||
String ownerExternalIdStored = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_OWNER_EXTERNAL_ID);
|
||||
|
||||
List<List<String>> data = table.asLists();
|
||||
for (int i = 1; i < data.size(); i++) {
|
||||
List<String> expectedValues = data.get(i);
|
||||
expectedValues.add(ownerExternalIdStored);
|
||||
expectedValues.add(loanId == null ? null : String.valueOf(loanId));
|
||||
expectedValues.add(loanExternalId);
|
||||
|
||||
List<List<String>> actualValuesList = content.stream().map(t -> {
|
||||
List<String> actualValues = new ArrayList<>();
|
||||
actualValues.add(t.getSettlementDate() == null ? null : FORMATTER.format(t.getSettlementDate()));
|
||||
actualValues.add(t.getPurchasePriceRatio() == null ? null : t.getPurchasePriceRatio());
|
||||
actualValues.add(t.getStatus() == null ? null : String.valueOf(t.getStatus()));
|
||||
actualValues.add(t.getEffectiveFrom() == null ? null : FORMATTER.format(t.getEffectiveFrom()));
|
||||
actualValues.add(t.getEffectiveTo() == null ? null : FORMATTER.format(t.getEffectiveTo()));
|
||||
actualValues.add(t.getOwner().getExternalId() == null ? null : t.getOwner().getExternalId());
|
||||
actualValues.add(loanId == null ? null : String.valueOf(t.getLoan().getLoanId()));
|
||||
actualValues.add(loanExternalId == null ? null : t.getLoan().getExternalId());
|
||||
return actualValues;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
boolean containsExpectedValues = actualValuesList.stream().anyMatch(actualValues -> actualValues.equals(expectedValues));
|
||||
|
||||
assertThat(numberOfElementsActual)
|
||||
.as(ErrorMessageHelper.wrongTotalFilteredRecordsInAssetExternalizationDetails(numberOfElementsActual, numberOfElements))
|
||||
.isEqualTo(numberOfElements);
|
||||
assertThat(containsExpectedValues).as(ErrorMessageHelper.wrongValueInExternalAssetDetails(i, actualValuesList, expectedValues))
|
||||
.isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@When("Admin send {string} command on {string} transaction it will throw an error")
|
||||
public void adminSendCommandAndItWillThrowError(String command, String transactionType) throws IOException {
|
||||
String transferExternalId;
|
||||
if (transactionType.equals(ExternalTransferData.StatusEnum.BUYBACK.getValue())) {
|
||||
transferExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_BUYBACK_TRANSFER_EXTERNAL_ID_FROM_RESPONSE);
|
||||
} else {
|
||||
transferExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_SALES_TRANSFER_EXTERNAL_ID_FROM_RESPONSE);
|
||||
}
|
||||
|
||||
Response<PostInitiateTransferResponse> response = externalAssetOwnersApi.transferRequestWithId1(transferExternalId, command)
|
||||
.execute();
|
||||
ErrorHelper.checkFailedApiCall(response, 403);
|
||||
}
|
||||
|
||||
@When("Admin send {string} command on {string} transaction")
|
||||
public void adminSendCommand(String command, String transactionType) throws IOException {
|
||||
String transferExternalId;
|
||||
if (transactionType.equals(ExternalTransferData.StatusEnum.BUYBACK.getValue())) {
|
||||
transferExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_BUYBACK_TRANSFER_EXTERNAL_ID_FROM_RESPONSE);
|
||||
} else {
|
||||
transferExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_SALES_TRANSFER_EXTERNAL_ID_FROM_RESPONSE);
|
||||
}
|
||||
|
||||
Response<PostInitiateTransferResponse> response = externalAssetOwnersApi.transferRequestWithId1(transferExternalId, command)
|
||||
.execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
}
|
||||
|
||||
@When("Admin makes asset externalization request for type {string} by Loan ID with unique ownerExternalId, force generated transferExternalId and without change test owner with following data:")
|
||||
public void createAssetExternalizationRequestByLoanIdUserGeneratedExtIdForceTransferIdNoTestOwner(String type, DataTable table)
|
||||
throws IOException {
|
||||
// if user created transferExternalId previously, it will use that, otherwise create a new one
|
||||
String transferExternalId = Utils.randomNameGenerator("TestTransferExtId_", 3);
|
||||
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_TRANSFER_EXTERNAL_ID_USER_GENERATED + "_" + type, transferExternalId);
|
||||
|
||||
createAssetExternalizationRequestByLoanId(table, transferExternalId, false);
|
||||
}
|
||||
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.common;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.cucumber.java.en.Then;
|
||||
import io.cucumber.java.en.When;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import org.apache.fineract.client.models.BusinessDateResponse;
|
||||
import org.apache.fineract.client.services.BusinessDateManagementApi;
|
||||
import org.apache.fineract.test.helper.BusinessDateHelper;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class BusinessDateStepDef extends AbstractStepDef {
|
||||
|
||||
@Autowired
|
||||
private BusinessDateHelper businessDateHelper;
|
||||
|
||||
@Autowired
|
||||
private BusinessDateManagementApi businessDateManagementApi;
|
||||
|
||||
@When("Admin sets the business date to {string}")
|
||||
public void setBusinessDate(String businessDate) throws IOException {
|
||||
businessDateHelper.setBusinessDate(businessDate);
|
||||
}
|
||||
|
||||
@When("Admin sets the business date to the actual date")
|
||||
public void setBusinessDateToday() throws IOException {
|
||||
businessDateHelper.setBusinessDateToday();
|
||||
}
|
||||
|
||||
@Then("Admin checks that the business date is correctly set to {string}")
|
||||
public void checkBusinessDate(String businessDate) throws IOException {
|
||||
Response<BusinessDateResponse> businessDateResponse = businessDateManagementApi.getBusinessDate(BusinessDateHelper.BUSINESS_DATE)
|
||||
.execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(businessDateResponse);
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d MMMM yyyy");
|
||||
LocalDate localDate = LocalDate.parse(businessDate, formatter);
|
||||
|
||||
assertThat(businessDateResponse.body().getDate()).isEqualTo(localDate);
|
||||
}
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.common;
|
||||
|
||||
import io.cucumber.java.en.Given;
|
||||
import io.cucumber.java.en.Then;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.client.models.BusinessStep;
|
||||
import org.apache.fineract.client.models.UpdateBusinessStepConfigRequest;
|
||||
import org.apache.fineract.client.services.BusinessStepConfigurationApi;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class BusinessStepStepDef extends AbstractStepDef {
|
||||
|
||||
private static final String WORKFLOW_NAME_LOAN_CLOSE_OF_BUSINESS = "LOAN_CLOSE_OF_BUSINESS";
|
||||
private static final String BUSINESS_STEP_NAME_APPLY_CHARGE_TO_OVERDUE_LOANS = "APPLY_CHARGE_TO_OVERDUE_LOANS";
|
||||
private static final String BUSINESS_STEP_NAME_LOAN_DELINQUENCY_CLASSIFICATION = "LOAN_DELINQUENCY_CLASSIFICATION";
|
||||
private static final String BUSINESS_STEP_NAME_CHECK_LOAN_REPAYMENT_DUE = "CHECK_LOAN_REPAYMENT_DUE";
|
||||
private static final String BUSINESS_STEP_NAME_CHECK_LOAN_REPAYMENT_OVERDUE = "CHECK_LOAN_REPAYMENT_OVERDUE";
|
||||
private static final String BUSINESS_STEP_NAME_UPDATE_LOAN_ARREARS_AGING = "UPDATE_LOAN_ARREARS_AGING";
|
||||
private static final String BUSINESS_STEP_NAME_ADD_PERIODIC_ACCRUAL_ENTRIES = "ADD_PERIODIC_ACCRUAL_ENTRIES";
|
||||
private static final String BUSINESS_STEP_NAME_EXTERNAL_ASSET_OWNER_TRANSFER = "EXTERNAL_ASSET_OWNER_TRANSFER";
|
||||
private static final String BUSINESS_STEP_NAME_CHECK_DUE_INSTALLMENTS = "CHECK_DUE_INSTALLMENTS";
|
||||
|
||||
@Autowired
|
||||
private BusinessStepConfigurationApi businessStepConfigurationApi;
|
||||
|
||||
@Given("Admin puts EXTERNAL_ASSET_OWNER_TRANSFER job into LOAN_CLOSE_OF_BUSINESS workflow")
|
||||
public void putExternalAssetOwnerTransferJobInCOB() throws IOException {
|
||||
BusinessStep applyChargeToOverdueLoans = new BusinessStep().stepName(BUSINESS_STEP_NAME_APPLY_CHARGE_TO_OVERDUE_LOANS).order(1L);
|
||||
BusinessStep loanDelinquencyClassification = new BusinessStep().stepName(BUSINESS_STEP_NAME_LOAN_DELINQUENCY_CLASSIFICATION)
|
||||
.order(2L);
|
||||
BusinessStep checkLoanRepaymentDue = new BusinessStep().stepName(BUSINESS_STEP_NAME_CHECK_LOAN_REPAYMENT_DUE).order(3L);
|
||||
BusinessStep checkLoanRepaymentOverdue = new BusinessStep().stepName(BUSINESS_STEP_NAME_CHECK_LOAN_REPAYMENT_OVERDUE).order(4L);
|
||||
BusinessStep updateLoanArrearsAging = new BusinessStep().stepName(BUSINESS_STEP_NAME_UPDATE_LOAN_ARREARS_AGING).order(5L);
|
||||
BusinessStep addPeriodicAccrualEntries = new BusinessStep().stepName(BUSINESS_STEP_NAME_ADD_PERIODIC_ACCRUAL_ENTRIES).order(6L);
|
||||
BusinessStep externalAssetOwnerTransfer = new BusinessStep().stepName(BUSINESS_STEP_NAME_EXTERNAL_ASSET_OWNER_TRANSFER).order(7L);
|
||||
|
||||
List<BusinessStep> businessSteps = new ArrayList<>();
|
||||
businessSteps.add(applyChargeToOverdueLoans);
|
||||
businessSteps.add(loanDelinquencyClassification);
|
||||
businessSteps.add(checkLoanRepaymentDue);
|
||||
businessSteps.add(checkLoanRepaymentOverdue);
|
||||
businessSteps.add(updateLoanArrearsAging);
|
||||
businessSteps.add(addPeriodicAccrualEntries);
|
||||
businessSteps.add(externalAssetOwnerTransfer);
|
||||
|
||||
UpdateBusinessStepConfigRequest request = new UpdateBusinessStepConfigRequest().businessSteps(businessSteps);
|
||||
|
||||
Response<Void> response = businessStepConfigurationApi.updateJobBusinessStepConfig(WORKFLOW_NAME_LOAN_CLOSE_OF_BUSINESS, request)
|
||||
.execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
}
|
||||
|
||||
@Then("Admin removes EXTERNAL_ASSET_OWNER_TRANSFER job from LOAN_CLOSE_OF_BUSINESS workflow")
|
||||
public void removeExternalAssetOwnerTransferJobInCOB() throws IOException {
|
||||
BusinessStep applyChargeToOverdueLoans = new BusinessStep().stepName(BUSINESS_STEP_NAME_APPLY_CHARGE_TO_OVERDUE_LOANS).order(1L);
|
||||
BusinessStep loanDelinquencyClassification = new BusinessStep().stepName(BUSINESS_STEP_NAME_LOAN_DELINQUENCY_CLASSIFICATION)
|
||||
.order(2L);
|
||||
BusinessStep checkLoanRepaymentDue = new BusinessStep().stepName(BUSINESS_STEP_NAME_CHECK_LOAN_REPAYMENT_DUE).order(3L);
|
||||
BusinessStep checkLoanRepaymentOverdue = new BusinessStep().stepName(BUSINESS_STEP_NAME_CHECK_LOAN_REPAYMENT_OVERDUE).order(4L);
|
||||
BusinessStep updateLoanArrearsAging = new BusinessStep().stepName(BUSINESS_STEP_NAME_UPDATE_LOAN_ARREARS_AGING).order(5L);
|
||||
BusinessStep addPeriodicAccrualEntries = new BusinessStep().stepName(BUSINESS_STEP_NAME_ADD_PERIODIC_ACCRUAL_ENTRIES).order(6L);
|
||||
|
||||
List<BusinessStep> businessSteps = new ArrayList<>();
|
||||
businessSteps.add(applyChargeToOverdueLoans);
|
||||
businessSteps.add(loanDelinquencyClassification);
|
||||
businessSteps.add(checkLoanRepaymentDue);
|
||||
businessSteps.add(checkLoanRepaymentOverdue);
|
||||
businessSteps.add(updateLoanArrearsAging);
|
||||
businessSteps.add(addPeriodicAccrualEntries);
|
||||
|
||||
UpdateBusinessStepConfigRequest request = new UpdateBusinessStepConfigRequest().businessSteps(businessSteps);
|
||||
|
||||
Response<Void> response = businessStepConfigurationApi.updateJobBusinessStepConfig(WORKFLOW_NAME_LOAN_CLOSE_OF_BUSINESS, request)
|
||||
.execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
}
|
||||
|
||||
@Given("Admin puts CHECK_DUE_INSTALLMENTS job into LOAN_CLOSE_OF_BUSINESS workflow")
|
||||
public void putCheckDueInstallmentsJobInCOB() throws IOException {
|
||||
BusinessStep applyChargeToOverdueLoans = new BusinessStep().stepName(BUSINESS_STEP_NAME_APPLY_CHARGE_TO_OVERDUE_LOANS).order(1L);
|
||||
BusinessStep loanDelinquencyClassification = new BusinessStep().stepName(BUSINESS_STEP_NAME_LOAN_DELINQUENCY_CLASSIFICATION)
|
||||
.order(2L);
|
||||
BusinessStep checkLoanRepaymentDue = new BusinessStep().stepName(BUSINESS_STEP_NAME_CHECK_LOAN_REPAYMENT_DUE).order(3L);
|
||||
BusinessStep checkLoanRepaymentOverdue = new BusinessStep().stepName(BUSINESS_STEP_NAME_CHECK_LOAN_REPAYMENT_OVERDUE).order(4L);
|
||||
BusinessStep updateLoanArrearsAging = new BusinessStep().stepName(BUSINESS_STEP_NAME_UPDATE_LOAN_ARREARS_AGING).order(5L);
|
||||
BusinessStep addPeriodicAccrualEntries = new BusinessStep().stepName(BUSINESS_STEP_NAME_ADD_PERIODIC_ACCRUAL_ENTRIES).order(6L);
|
||||
BusinessStep checkDueInstallments = new BusinessStep().stepName(BUSINESS_STEP_NAME_CHECK_DUE_INSTALLMENTS).order(7L);
|
||||
|
||||
List<BusinessStep> businessSteps = new ArrayList<>();
|
||||
businessSteps.add(applyChargeToOverdueLoans);
|
||||
businessSteps.add(loanDelinquencyClassification);
|
||||
businessSteps.add(checkLoanRepaymentDue);
|
||||
businessSteps.add(checkLoanRepaymentOverdue);
|
||||
businessSteps.add(updateLoanArrearsAging);
|
||||
businessSteps.add(addPeriodicAccrualEntries);
|
||||
businessSteps.add(checkDueInstallments);
|
||||
|
||||
UpdateBusinessStepConfigRequest request = new UpdateBusinessStepConfigRequest().businessSteps(businessSteps);
|
||||
|
||||
Response<Void> response = businessStepConfigurationApi.updateJobBusinessStepConfig(WORKFLOW_NAME_LOAN_CLOSE_OF_BUSINESS, request)
|
||||
.execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
}
|
||||
|
||||
@Then("Admin removes CHECK_DUE_INSTALLMENTS job from LOAN_CLOSE_OF_BUSINESS workflow")
|
||||
public void removeCheckDueInstallmentsJobInCOB() throws IOException {
|
||||
BusinessStep applyChargeToOverdueLoans = new BusinessStep().stepName(BUSINESS_STEP_NAME_APPLY_CHARGE_TO_OVERDUE_LOANS).order(1L);
|
||||
BusinessStep loanDelinquencyClassification = new BusinessStep().stepName(BUSINESS_STEP_NAME_LOAN_DELINQUENCY_CLASSIFICATION)
|
||||
.order(2L);
|
||||
BusinessStep checkLoanRepaymentDue = new BusinessStep().stepName(BUSINESS_STEP_NAME_CHECK_LOAN_REPAYMENT_DUE).order(3L);
|
||||
BusinessStep checkLoanRepaymentOverdue = new BusinessStep().stepName(BUSINESS_STEP_NAME_CHECK_LOAN_REPAYMENT_OVERDUE).order(4L);
|
||||
BusinessStep updateLoanArrearsAging = new BusinessStep().stepName(BUSINESS_STEP_NAME_UPDATE_LOAN_ARREARS_AGING).order(5L);
|
||||
BusinessStep addPeriodicAccrualEntries = new BusinessStep().stepName(BUSINESS_STEP_NAME_ADD_PERIODIC_ACCRUAL_ENTRIES).order(6L);
|
||||
|
||||
List<BusinessStep> businessSteps = new ArrayList<>();
|
||||
businessSteps.add(applyChargeToOverdueLoans);
|
||||
businessSteps.add(loanDelinquencyClassification);
|
||||
businessSteps.add(checkLoanRepaymentDue);
|
||||
businessSteps.add(checkLoanRepaymentOverdue);
|
||||
businessSteps.add(updateLoanArrearsAging);
|
||||
businessSteps.add(addPeriodicAccrualEntries);
|
||||
|
||||
UpdateBusinessStepConfigRequest request = new UpdateBusinessStepConfigRequest().businessSteps(businessSteps);
|
||||
|
||||
Response<Void> response = businessStepConfigurationApi.updateJobBusinessStepConfig(WORKFLOW_NAME_LOAN_CLOSE_OF_BUSINESS, request)
|
||||
.execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
}
|
||||
}
|
||||
+10
@@ -33,6 +33,7 @@ import org.apache.fineract.test.helper.CodeHelper;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.helper.ErrorMessageHelper;
|
||||
import org.apache.fineract.test.helper.Utils;
|
||||
import org.apache.fineract.test.messaging.event.EventCheckHelper;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.apache.fineract.test.support.TestContextKey;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -49,6 +50,9 @@ public class ClientStepDef extends AbstractStepDef {
|
||||
@Autowired
|
||||
private ClientRequestFactory clientRequestFactory;
|
||||
|
||||
@Autowired
|
||||
private EventCheckHelper eventCheckHelper;
|
||||
|
||||
@When("Admin creates a client with random data")
|
||||
public void createClientRandomFirstNameLastName() throws IOException {
|
||||
PostClientsRequest clientsRequest = clientRequestFactory.defaultClientCreationRequest();
|
||||
@@ -56,6 +60,8 @@ public class ClientStepDef extends AbstractStepDef {
|
||||
Response<PostClientsResponse> response = clientApi.create6(clientsRequest).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
testContext().set(TestContextKey.CLIENT_CREATE_RESPONSE, response);
|
||||
|
||||
eventCheckHelper.clientEventCheck(response);
|
||||
}
|
||||
|
||||
@When("Admin creates a second client with random data")
|
||||
@@ -65,6 +71,8 @@ public class ClientStepDef extends AbstractStepDef {
|
||||
Response<PostClientsResponse> response = clientApi.create6(clientsRequest).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
testContext().set(TestContextKey.CLIENT_CREATE_SECOND_CLIENT_RESPONSE, response);
|
||||
|
||||
eventCheckHelper.clientEventCheck(response);
|
||||
}
|
||||
|
||||
@When("Admin creates a client with Firstname {string} and Lastname {string}")
|
||||
@@ -114,5 +122,7 @@ public class ClientStepDef extends AbstractStepDef {
|
||||
Response<PostClientsResponse> response = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE);
|
||||
|
||||
assertThat(response.isSuccessful()).as(ErrorMessageHelper.requestFailed(response)).isTrue();
|
||||
|
||||
eventCheckHelper.clientEventCheck(response);
|
||||
}
|
||||
}
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.common;
|
||||
|
||||
import io.cucumber.java.en.Then;
|
||||
import io.github.classgraph.ClassGraph;
|
||||
import io.github.classgraph.ClassInfoList;
|
||||
import io.github.classgraph.ScanResult;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.test.messaging.EventAssertion;
|
||||
import org.apache.fineract.test.messaging.event.Event;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.apache.fineract.test.support.TestContextKey;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import retrofit2.Response;
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public class EventStepDef extends AbstractStepDef {
|
||||
|
||||
@Autowired
|
||||
private EventAssertion eventAssertion;
|
||||
|
||||
@Then("{string} event has been raised for the loan")
|
||||
public void assertEventRaisedForLoan(String eventType) {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
Class<? extends Event> eventTypeClazz = resolveEventType(eventType);
|
||||
eventAssertion.assertEventRaised(eventTypeClazz, loanId);
|
||||
}
|
||||
|
||||
@Then("No new event with type {string} has been raised for the loan")
|
||||
public void assertEventNotRaisedForLoan(String eventType) {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
Class<? extends Event> eventTypeClazz = resolveEventType(eventType);
|
||||
eventAssertion.assertEventNotRaised(eventTypeClazz, loanId);
|
||||
}
|
||||
|
||||
private Class<? extends Event> resolveEventType(String eventType) {
|
||||
String fullyQualifiedEventClassName = null;
|
||||
try (ScanResult scanResult = new ClassGraph().enableAllInfo().acceptPackages("org.apache.fineract.test").scan()) {
|
||||
ClassInfoList matchingClasses = scanResult.getAllClasses().filter(i -> i.getSimpleName().equalsIgnoreCase(eventType));
|
||||
if (matchingClasses.isEmpty()) {
|
||||
throw new IllegalArgumentException("Cannot find event with type name: " + eventType);
|
||||
}
|
||||
fullyQualifiedEventClassName = matchingClasses.get(0).getName();
|
||||
}
|
||||
|
||||
Class<? extends Event> eventTypeClazz = null;
|
||||
try {
|
||||
eventTypeClazz = (Class<? extends Event>) Class.forName(fullyQualifiedEventClassName);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot find event with type name: " + eventType, e);
|
||||
}
|
||||
return eventTypeClazz;
|
||||
}
|
||||
}
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.common;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.cucumber.datatable.DataTable;
|
||||
import io.cucumber.java.en.Then;
|
||||
import java.io.IOException;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.client.models.GetJournalEntriesTransactionIdResponse;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdTransactions;
|
||||
import org.apache.fineract.client.models.JournalEntryTransactionItem;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.services.JournalEntriesApi;
|
||||
import org.apache.fineract.client.services.LoansApi;
|
||||
import org.apache.fineract.test.data.TransactionType;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.helper.ErrorMessageHelper;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.apache.fineract.test.support.TestContextKey;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import retrofit2.Response;
|
||||
|
||||
@Slf4j
|
||||
public class JournalEntriesStepDef extends AbstractStepDef {
|
||||
|
||||
public static final String DATE_FORMAT = "dd MMMM yyyy";
|
||||
|
||||
@Autowired
|
||||
private LoansApi loansApi;
|
||||
|
||||
@Autowired
|
||||
private JournalEntriesApi journalEntriesApi;
|
||||
|
||||
@Then("Loan Transactions tab has a {string} transaction with date {string} which has the following Journal entries:")
|
||||
public void journalEntryDataCheck(String transactionType, String transactionDate, DataTable table) throws IOException {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse);
|
||||
|
||||
TransactionType transactionType1 = TransactionType.valueOf(transactionType);
|
||||
String transactionTypeExpected = transactionType1.getValue();
|
||||
|
||||
List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions();
|
||||
|
||||
List<GetLoansLoanIdTransactions> transactionsMatch = transactions.stream()
|
||||
.filter(t -> transactionDate.equals(formatter.format(t.getDate()))
|
||||
&& transactionTypeExpected.equals(t.getType().getCode().substring(20)))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<List<JournalEntryTransactionItem>> journalLinesActualList = transactionsMatch.stream().map(t -> {
|
||||
String transactionId = "L" + t.getId();
|
||||
Response<GetJournalEntriesTransactionIdResponse> journalEntryDataResponse = null;
|
||||
try {
|
||||
journalEntryDataResponse = journalEntriesApi.retrieveAll1(//
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
transactionId, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
true//
|
||||
).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(journalEntryDataResponse);
|
||||
} catch (IOException e) {
|
||||
log.error("Exception", e);
|
||||
}
|
||||
|
||||
return journalEntryDataResponse.body().getPageItems();
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
List<List<String>> data = table.asLists();
|
||||
for (int i = 1; i < data.size(); i++) {
|
||||
List<List<List<String>>> possibleActualValuesList = new ArrayList<>();
|
||||
List<String> expectedValues = data.get(i);
|
||||
boolean containsAnyExpected = false;
|
||||
|
||||
for (int j = 0; j < journalLinesActualList.size(); j++) {
|
||||
List<JournalEntryTransactionItem> journalLinesActual = journalLinesActualList.get(j);
|
||||
|
||||
List<List<String>> actualValuesList = journalLinesActual.stream().map(t -> {
|
||||
List<String> actualValues = new ArrayList<>();
|
||||
actualValues.add(t.getGlAccountType().getValue() == null ? null : t.getGlAccountType().getValue());
|
||||
actualValues.add(t.getGlAccountCode() == null ? null : t.getGlAccountCode());
|
||||
actualValues.add(t.getGlAccountName() == null ? null : t.getGlAccountName());
|
||||
actualValues.add("DEBIT".equals(t.getEntryType().getValue()) ? String.valueOf(t.getAmount()) : null);
|
||||
actualValues.add("CREDIT".equals(t.getEntryType().getValue()) ? String.valueOf(t.getAmount()) : null);
|
||||
|
||||
return actualValues;
|
||||
}).collect(Collectors.toList());
|
||||
possibleActualValuesList.add(actualValuesList);
|
||||
|
||||
boolean containsExpectedValues = actualValuesList.stream().anyMatch(actualValues -> actualValues.equals(expectedValues));
|
||||
if (containsExpectedValues) {
|
||||
containsAnyExpected = true;
|
||||
}
|
||||
}
|
||||
assertThat(containsAnyExpected)
|
||||
.as(ErrorMessageHelper.wrongValueInLineInJournalEntries(i, possibleActualValuesList, expectedValues)).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Then("In Loan transactions the replayed {string} transaction with date {string} has a reverted transaction pair with the following Journal entries:")
|
||||
public void revertedJournalEntryDataCheck(String transactionType, String transactionDate, DataTable table) throws IOException {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse);
|
||||
|
||||
TransactionType transactionType1 = TransactionType.valueOf(transactionType);
|
||||
String transactionTypeExpected = transactionType1.getValue();
|
||||
|
||||
List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions();
|
||||
|
||||
List<GetLoansLoanIdTransactions> transactionsMatch = transactions.stream()
|
||||
.filter(t -> transactionDate.equals(formatter.format(t.getDate()))
|
||||
&& transactionTypeExpected.equals(t.getType().getCode().substring(20)))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<String> transactionIdList = transactionsMatch.stream().flatMap(t -> t.getTransactionRelations().stream()
|
||||
.filter(e -> "REPLAYED".equals(e.getRelationType())).map(c -> "L" + c.getToLoanTransaction().toString()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<List<JournalEntryTransactionItem>> journalLinesActualList = transactionIdList.stream().map(t -> {
|
||||
Response<GetJournalEntriesTransactionIdResponse> journalEntryDataResponse = null;
|
||||
try {
|
||||
journalEntryDataResponse = journalEntriesApi.retrieveAll1(//
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
t, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
null, //
|
||||
true//
|
||||
).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(journalEntryDataResponse);
|
||||
} catch (IOException e) {
|
||||
log.error("Exception", e);
|
||||
}
|
||||
|
||||
return journalEntryDataResponse.body().getPageItems();
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
List<List<String>> data = table.asLists();
|
||||
for (int i = 1; i < data.size(); i++) {
|
||||
List<List<List<String>>> possibleActualValuesList = new ArrayList<>();
|
||||
List<String> expectedValues = data.get(i);
|
||||
boolean containsAnyExpected = false;
|
||||
|
||||
for (int j = 0; j < journalLinesActualList.size(); j++) {
|
||||
List<JournalEntryTransactionItem> journalLinesActual = journalLinesActualList.get(j);
|
||||
|
||||
List<List<String>> actualValuesList = journalLinesActual.stream().map(t -> {
|
||||
List<String> actualValues = new ArrayList<>();
|
||||
actualValues.add(t.getGlAccountType().getValue() == null ? null : t.getGlAccountType().getValue());
|
||||
actualValues.add(t.getGlAccountCode() == null ? null : t.getGlAccountCode());
|
||||
actualValues.add(t.getGlAccountName() == null ? null : t.getGlAccountName());
|
||||
actualValues.add("DEBIT".equals(t.getEntryType().getValue()) ? String.valueOf(t.getAmount()) : null);
|
||||
actualValues.add("CREDIT".equals(t.getEntryType().getValue()) ? String.valueOf(t.getAmount()) : null);
|
||||
|
||||
return actualValues;
|
||||
}).collect(Collectors.toList());
|
||||
possibleActualValuesList.add(actualValuesList);
|
||||
|
||||
boolean containsExpectedValues = actualValuesList.stream().anyMatch(actualValues -> actualValues.equals(expectedValues));
|
||||
if (containsExpectedValues) {
|
||||
containsAnyExpected = true;
|
||||
}
|
||||
}
|
||||
assertThat(containsAnyExpected)
|
||||
.as(ErrorMessageHelper.wrongValueInLineInJournalEntries(i, possibleActualValuesList, expectedValues)).isTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.common;
|
||||
|
||||
import io.cucumber.java.en.And;
|
||||
import io.cucumber.java.en.When;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.test.data.job.DefaultJob;
|
||||
import org.apache.fineract.test.service.JobService;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@Slf4j
|
||||
public class SchedulerStepDef extends AbstractStepDef {
|
||||
|
||||
@Autowired
|
||||
private JobService jobService;
|
||||
|
||||
@And("Admin runs the Add Accrual Transactions job")
|
||||
public void runAccrualTransaction() {
|
||||
jobService.executeAndWait(DefaultJob.ADD_ACCRUAL_TRANSACTIONS);
|
||||
}
|
||||
|
||||
@And("Admin runs the Add Periodic Accrual Transactions job")
|
||||
public void runPeriodicAccrualTransaction() {
|
||||
jobService.executeAndWait(DefaultJob.ADD_PERIODIC_ACCRUAL_TRANSACTIONS);
|
||||
}
|
||||
|
||||
@And("Admin runs the Increase Business Date by 1 day job")
|
||||
public void runIncreaseBusinessDate() {
|
||||
jobService.executeAndWait(DefaultJob.INCREASE_BUSINESS_DAY);
|
||||
}
|
||||
|
||||
@And("Admin runs the Loan Delinquency Classification job")
|
||||
public void runLoanDelinquencyClassification() {
|
||||
jobService.executeAndWait(DefaultJob.LOAN_DELINQUENCY_CLASSIFICATION);
|
||||
}
|
||||
|
||||
@When("Admin runs COB job")
|
||||
public void runCOB() {
|
||||
jobService.executeAndWait(DefaultJob.LOAN_COB);
|
||||
}
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.common;
|
||||
|
||||
import io.cucumber.java.en.When;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.fineract.client.models.GetRolesResponse;
|
||||
import org.apache.fineract.client.models.PostRolesRequest;
|
||||
import org.apache.fineract.client.models.PostRolesResponse;
|
||||
import org.apache.fineract.client.models.PostUsersRequest;
|
||||
import org.apache.fineract.client.models.PostUsersResponse;
|
||||
import org.apache.fineract.client.models.PutRolesRoleIdPermissionsRequest;
|
||||
import org.apache.fineract.client.models.PutRolesRoleIdPermissionsResponse;
|
||||
import org.apache.fineract.client.services.RolesApi;
|
||||
import org.apache.fineract.client.services.UsersApi;
|
||||
import org.apache.fineract.test.api.ApiProperties;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.helper.Utils;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.apache.fineract.test.support.TestContextKey;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class UserStepDef extends AbstractStepDef {
|
||||
|
||||
private static final String EMAIL = "test@test.com";
|
||||
|
||||
@Autowired
|
||||
private RolesApi rolesApi;
|
||||
|
||||
@Autowired
|
||||
private UsersApi usersApi;
|
||||
|
||||
@Autowired
|
||||
private ApiProperties apiProperties;
|
||||
|
||||
@When("Admin creates new user with {string} username, {string} role name and given permissions:")
|
||||
public void createUserWithUsernameAndRoles(String username, String roleName, List<String> permissions) throws IOException {
|
||||
Response<List<GetRolesResponse>> retrieveAllRolesResponse = rolesApi.retrieveAllRoles().execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(retrieveAllRolesResponse);
|
||||
PostRolesRequest newRoleRequest = new PostRolesRequest().name(Utils.randomNameGenerator(roleName, 8)).description(roleName);
|
||||
Response<PostRolesResponse> createNewRole = rolesApi.createRole(newRoleRequest).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(createNewRole);
|
||||
Long roleId = createNewRole.body().getResourceId();
|
||||
Map<String, Boolean> permissionMap = new HashMap<>();
|
||||
permissions.forEach(role -> permissionMap.put(role, true));
|
||||
PutRolesRoleIdPermissionsRequest putRolesRoleIdPermissionsRequest = new PutRolesRoleIdPermissionsRequest()
|
||||
.permissions(permissionMap);
|
||||
Response<PutRolesRoleIdPermissionsResponse> updateRolePermissionResponse = rolesApi
|
||||
.updateRolePermissions(roleId, putRolesRoleIdPermissionsRequest).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(updateRolePermissionResponse);
|
||||
|
||||
PostUsersRequest postUsersRequest = new PostUsersRequest() //
|
||||
.username(Utils.randomNameGenerator(username, 8)) //
|
||||
.email(EMAIL) //
|
||||
.firstname(username) //
|
||||
.lastname(username) //
|
||||
.sendPasswordToEmail(Boolean.FALSE) //
|
||||
.officeId(1L) //
|
||||
.password(apiProperties.getPassword()) //
|
||||
.repeatPassword(apiProperties.getPassword()) //
|
||||
.roles(List.of(roleId));
|
||||
|
||||
Response<PostUsersResponse> createUserResponse = usersApi.create15(postUsersRequest).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(createUserResponse);
|
||||
testContext().set(TestContextKey.CREATED_SIMPLE_USER_RESPONSE, createUserResponse);
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.loan;
|
||||
|
||||
import io.cucumber.java.en.Then;
|
||||
import io.cucumber.java.en.When;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import org.apache.fineract.client.models.InlineJobRequest;
|
||||
import org.apache.fineract.client.models.InlineJobResponse;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.services.ExternalEventConfigurationApi;
|
||||
import org.apache.fineract.client.services.InlineJobApi;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.messaging.EventAssertion;
|
||||
import org.apache.fineract.test.messaging.event.assetexternalization.LoanAccountCustomSnapshotEvent;
|
||||
import org.apache.fineract.test.messaging.event.loan.repayment.LoanRepaymentDueEvent;
|
||||
import org.apache.fineract.test.messaging.event.loan.repayment.LoanRepaymentOverdueEvent;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.apache.fineract.test.support.TestContextKey;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class InlineCOBStepDef extends AbstractStepDef {
|
||||
|
||||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd MMMM yyyy");
|
||||
|
||||
@Autowired
|
||||
private InlineJobApi inlineJobApi;
|
||||
|
||||
@Autowired
|
||||
private EventAssertion eventAssertion;
|
||||
|
||||
@Autowired
|
||||
ExternalEventConfigurationApi eventConfigurationApi;
|
||||
|
||||
@When("Admin runs inline COB job for Loan")
|
||||
public void runInlineCOB() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
InlineJobRequest inlineJobRequest = new InlineJobRequest().addLoanIdsItem(loanId);
|
||||
|
||||
Response<InlineJobResponse> inlineJobResponse = inlineJobApi.executeInlineJob("LOAN_COB", inlineJobRequest).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(inlineJobResponse);
|
||||
}
|
||||
|
||||
@Then("Loan Repayment Due Business Event is created")
|
||||
public void checkLoanRepaymentDueBusinessEventCreated() {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
eventAssertion.assertEventRaised(LoanRepaymentDueEvent.class, loanId);
|
||||
}
|
||||
|
||||
@Then("Loan Repayment Overdue Business Event is created")
|
||||
public void checkLoanRepaymentOverdueBusinessEventCreated() {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
eventAssertion.assertEventRaised(LoanRepaymentOverdueEvent.class, loanId);
|
||||
}
|
||||
|
||||
@Then("LoanAccountCustomSnapshotBusinessEvent is created with business date {string}")
|
||||
public void checkLoanRepaymentDueBusinessEventCreatedWithBusinessDate(String expectedBusinessDate) {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
LocalDate expectedBusinessDateParsed = LocalDate.parse(expectedBusinessDate, FORMATTER);
|
||||
eventAssertion.assertEvent(LoanAccountCustomSnapshotEvent.class, loanId).isRaisedOnBusinessDate(expectedBusinessDateParsed);
|
||||
}
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.loan;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.cucumber.java.en.Then;
|
||||
import io.cucumber.java.en.When;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.client.models.GetLoanAccountLockResponse;
|
||||
import org.apache.fineract.client.models.GetOldestCOBProcessedLoanResponse;
|
||||
import org.apache.fineract.client.models.LoanAccountLock;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.services.DefaultApi;
|
||||
import org.apache.fineract.client.services.LoanAccountLockApi;
|
||||
import org.apache.fineract.client.services.LoanCobCatchUpApi;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.helper.ErrorMessageHelper;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.apache.fineract.test.support.TestContextKey;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import retrofit2.Response;
|
||||
|
||||
@Slf4j
|
||||
public class LoanCOBStepDef extends AbstractStepDef {
|
||||
|
||||
@Autowired
|
||||
private LoanCobCatchUpApi loanCobCatchUpApi;
|
||||
|
||||
@Autowired
|
||||
private LoanAccountLockApi loanAccountLockApi;
|
||||
|
||||
@Autowired
|
||||
private DefaultApi defaultApi;
|
||||
|
||||
@Then("The cobProcessedDate of the oldest loan processed by COB is more than 1 day earlier than cobBusinessDate")
|
||||
public void checkOldestCOBProcessed() throws IOException {
|
||||
Response<GetOldestCOBProcessedLoanResponse> response = loanCobCatchUpApi.getOldestCOBProcessedLoan().execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
LocalDate cobDate = response.body().getCobBusinessDate();
|
||||
LocalDate cobDateMinusOne = cobDate.minusDays(1);
|
||||
LocalDate cobProcessedDate = response.body().getCobProcessedDate();
|
||||
log.info("cobDateMinusOne: {}", cobDateMinusOne);
|
||||
log.info("cobProcessedDate: {}", cobProcessedDate);
|
||||
|
||||
boolean result = cobDateMinusOne.isAfter(cobProcessedDate);
|
||||
assertThat(result).as(ErrorMessageHelper.wrongLastCOBProcessedLoanDate(cobProcessedDate, cobDateMinusOne)).isTrue();
|
||||
}
|
||||
|
||||
@Then("There are no locked loan accounts")
|
||||
public void listOfLockedLoansEmpty() throws IOException {
|
||||
Response<GetLoanAccountLockResponse> response = loanAccountLockApi.retrieveLockedAccounts(0, 1000).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
int size = response.body().getContent().size();
|
||||
assertThat(size).as(ErrorMessageHelper.listOfLockedLoansNotEmpty(response)).isEqualTo(0);
|
||||
log.info("Size of List of the locked loans: {}", size);
|
||||
}
|
||||
|
||||
@Then("The loan account is not locked")
|
||||
public void loanIsNotInListOfLockedLoans() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
Long targetLoanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoanAccountLockResponse> response = loanAccountLockApi.retrieveLockedAccounts(0, 1000).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
List<LoanAccountLock> content = response.body().getContent();
|
||||
boolean contains = content.stream()//
|
||||
.map(LoanAccountLock::getLoanId)//
|
||||
.anyMatch(targetLoanId::equals);//
|
||||
|
||||
assertThat(contains).as(ErrorMessageHelper.listOfLockedLoansContainsLoan(targetLoanId, response)).isFalse();
|
||||
}
|
||||
|
||||
@When("Admin places a lock on loan account with an error message")
|
||||
public void placeLockOnLoanAccountWithErrorMessage() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<Void> response = defaultApi.placeLockOnLoanAccount(loanId, "LOAN_COB_CHUNK_PROCESSING", "TestError").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
}
|
||||
|
||||
@When("Admin places a lock on loan account WITHOUT an error message")
|
||||
public void placeLockOnLoanAccountNoErrorMessage() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<Void> response = defaultApi.placeLockOnLoanAccount(loanId, "LOAN_COB_CHUNK_PROCESSING").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
}
|
||||
}
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.loan;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.cucumber.java.en.When;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.client.models.BusinessDateResponse;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdLoanChargeData;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdTransactions;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdRequest;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.services.BusinessDateManagementApi;
|
||||
import org.apache.fineract.client.services.LoanChargesApi;
|
||||
import org.apache.fineract.client.services.LoanTransactionsApi;
|
||||
import org.apache.fineract.client.services.LoansApi;
|
||||
import org.apache.fineract.client.util.JSON;
|
||||
import org.apache.fineract.test.data.ChargeProductType;
|
||||
import org.apache.fineract.test.factory.LoanRequestFactory;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.helper.ErrorMessageHelper;
|
||||
import org.apache.fineract.test.helper.ErrorResponse;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.apache.fineract.test.support.TestContextKey;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class LoanChargeAdjustmentStepDef extends AbstractStepDef {
|
||||
|
||||
public static final String DATE_FORMAT = "dd MMMM yyyy";
|
||||
|
||||
private static final Gson GSON = new JSON().getGson();
|
||||
|
||||
@Autowired
|
||||
private LoanChargesApi loanChargesApi;
|
||||
@Autowired
|
||||
private LoansApi loansApi;
|
||||
@Autowired
|
||||
private LoanTransactionsApi loanTransactionsApi;
|
||||
@Autowired
|
||||
private BusinessDateManagementApi businessDateManagementApi;
|
||||
|
||||
@When("Admin makes a charge adjustment for the last {string} type charge which is due on {string} with {double} EUR transaction amount and externalId {string}")
|
||||
public void makeLoanChargeAdjustment(String chargeTypeEnum, String date, Double transactionAmount, String externalId)
|
||||
throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "charges", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse);
|
||||
|
||||
Long transactionId = getTransactionIdForLastChargeMetConditions(chargeTypeEnum, date, loanDetailsResponse);
|
||||
makeChargeAdjustmentCall(loanId, transactionId, externalId, transactionAmount);
|
||||
}
|
||||
|
||||
@When("Admin makes a charge adjustment for the last {string} type charge which is due on {string} with transaction amount higher than the available charge amount")
|
||||
public void loanChargeAdjustmentFailedOnWrongAmount(String chargeTypeEnum, String date) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "charges", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse);
|
||||
|
||||
Long transactionId = getTransactionIdForLastChargeMetConditions(chargeTypeEnum, date, loanDetailsResponse);
|
||||
PostLoansLoanIdChargesChargeIdRequest chargeAdjustmentRequest = LoanRequestFactory.defaultChargeAdjustmentRequest().amount(8.0)
|
||||
.externalId("");
|
||||
|
||||
Response<PostLoansLoanIdChargesChargeIdResponse> chargeAdjustmentResponseFail = loanChargesApi
|
||||
.executeLoanCharge2(loanId, transactionId, chargeAdjustmentRequest, "adjustment").execute();
|
||||
|
||||
String string = chargeAdjustmentResponseFail.errorBody().string();
|
||||
ErrorResponse errorResponse = GSON.fromJson(string, ErrorResponse.class);
|
||||
Integer httpStatusCodeActual = errorResponse.getHttpStatusCode();
|
||||
String developerMessageActual = errorResponse.getErrors().get(0).getDeveloperMessage();
|
||||
|
||||
Integer httpStatusCodeExpected = 403;
|
||||
String developerMessageExpected = "Transaction amount cannot be higher than the available charge amount for adjustment: 7.000000";
|
||||
|
||||
assertThat(httpStatusCodeActual)
|
||||
.as(ErrorMessageHelper.wrongErrorCodeInFailedChargeAdjustment(httpStatusCodeActual, httpStatusCodeExpected))
|
||||
.isEqualTo(httpStatusCodeExpected);
|
||||
assertThat(developerMessageActual)
|
||||
.as(ErrorMessageHelper.wrongErrorMessageInFailedChargeAdjustment(developerMessageActual, developerMessageExpected))
|
||||
.isEqualTo(developerMessageExpected);
|
||||
}
|
||||
|
||||
@When("Admin reverts the charge adjustment which was raised on {string} with {double} EUR transaction amount")
|
||||
public void loanChargeAdjustmentUndo(String transactionDate, double transactionAmount) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse);
|
||||
|
||||
Long transactionId = getTransactionIdForTransactionMetConditions(transactionDate, transactionAmount, loanDetailsResponse);
|
||||
|
||||
Response<List<BusinessDateResponse>> businessDateResponse = businessDateManagementApi.getBusinessDates().execute();
|
||||
LocalDate businessDate = businessDateResponse.body().get(0).getDate();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
|
||||
String businessDateActual = formatter.format(businessDate);
|
||||
|
||||
PostLoansLoanIdTransactionsTransactionIdRequest chargeAdjustmentUndoRequest = LoanRequestFactory
|
||||
.defaultChargeAdjustmentTransactionUndoRequest().transactionDate(businessDateActual);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> chargeAdjustmentUndoResponse = loanTransactionsApi
|
||||
.adjustLoanTransaction(loanId, transactionId, chargeAdjustmentUndoRequest, "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(chargeAdjustmentUndoResponse);
|
||||
}
|
||||
|
||||
private Long getTransactionIdForTransactionMetConditions(String transactionDate, double transactionAmount,
|
||||
Response<GetLoansLoanIdResponse> loanDetailsResponse) {
|
||||
List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions();
|
||||
GetLoansLoanIdTransactions transactionMetConditions = new GetLoansLoanIdTransactions();
|
||||
for (int i = 0; i < transactions.size(); i++) {
|
||||
LocalDate date = transactions.get(i).getDate();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
|
||||
String dateActual = formatter.format(date);
|
||||
|
||||
Double amountActual = transactions.get(i).getAmount();
|
||||
|
||||
if (dateActual.equals(transactionDate) && amountActual.equals(transactionAmount)) {
|
||||
transactionMetConditions = transactions.get(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return transactionMetConditions.getId();
|
||||
}
|
||||
|
||||
private void makeChargeAdjustmentCall(Long loanId, Long transactionId, String externalId, double transactionAmount) throws IOException {
|
||||
PostLoansLoanIdChargesChargeIdRequest chargeAdjustmentRequest = LoanRequestFactory.defaultChargeAdjustmentRequest()
|
||||
.amount(transactionAmount).externalId(externalId);
|
||||
|
||||
Response<PostLoansLoanIdChargesChargeIdResponse> chargeAdjustmentResponse = loanChargesApi
|
||||
.executeLoanCharge2(loanId, transactionId, chargeAdjustmentRequest, "adjustment").execute();
|
||||
testContext().set(TestContextKey.LOAN_CHARGE_ADJUSTMENT_RESPONSE, chargeAdjustmentResponse);
|
||||
ErrorHelper.checkSuccessfulApiCall(chargeAdjustmentResponse);
|
||||
}
|
||||
|
||||
private Long getTransactionIdForLastChargeMetConditions(String chargeTypeEnum, String date,
|
||||
Response<GetLoansLoanIdResponse> loanDetailsResponse) {
|
||||
List<GetLoansLoanIdLoanChargeData> charges = loanDetailsResponse.body().getCharges();
|
||||
|
||||
ChargeProductType chargeType = ChargeProductType.valueOf(chargeTypeEnum);
|
||||
Long chargeProductId = chargeType.getValue();
|
||||
|
||||
List<GetLoansLoanIdLoanChargeData> resultList = new ArrayList<>();
|
||||
charges.forEach(charge -> {
|
||||
Long chargeId = charge.getChargeId();
|
||||
LocalDate dueDate = charge.getDueDate();
|
||||
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
|
||||
String chargeDueDate = formatter.format(dueDate);
|
||||
|
||||
if (chargeId.equals(chargeProductId) && chargeDueDate.equals(date)) {
|
||||
resultList.add(charge);
|
||||
}
|
||||
});
|
||||
|
||||
GetLoansLoanIdLoanChargeData lastChargeResult = resultList.get(resultList.size() - 1);
|
||||
return lastChargeResult.getId();
|
||||
}
|
||||
}
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.loan;
|
||||
|
||||
import io.cucumber.java.en.When;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1;
|
||||
import org.apache.fineract.avro.loan.v1.LoanTransactionEnumDataV1;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdTransactions;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdTransactionsTransactionIdResponse;
|
||||
import org.apache.fineract.client.models.GetLoansType;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.services.LoanTransactionsApi;
|
||||
import org.apache.fineract.client.services.LoansApi;
|
||||
import org.apache.fineract.test.data.paymenttype.DefaultPaymentType;
|
||||
import org.apache.fineract.test.data.paymenttype.PaymentTypeResolver;
|
||||
import org.apache.fineract.test.factory.LoanRequestFactory;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.messaging.EventAssertion;
|
||||
import org.apache.fineract.test.messaging.event.loan.LoanBalanceChangedEvent;
|
||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanChargebackTransactionEvent;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.apache.fineract.test.support.TestContextKey;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class LoanChargeBackStepDef extends AbstractStepDef {
|
||||
|
||||
@Autowired
|
||||
private LoanTransactionsApi loanTransactionsApi;
|
||||
|
||||
@Autowired
|
||||
private LoansApi loansApi;
|
||||
|
||||
@Autowired
|
||||
private EventAssertion eventAssertion;
|
||||
|
||||
@Autowired
|
||||
private PaymentTypeResolver paymentTypeResolver;
|
||||
|
||||
@When("Admin makes {string} chargeback with {double} EUR transaction amount")
|
||||
public void makeLoanChargeback(String repaymentType, double transactionAmount) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> repaymentResponse = testContext().get(TestContextKey.LOAN_REPAYMENT_RESPONSE);
|
||||
Long transactionId = Long.valueOf(repaymentResponse.body().getResourceId());
|
||||
|
||||
makeChargebackCall(loanId, transactionId, repaymentType, transactionAmount);
|
||||
}
|
||||
|
||||
@When("Admin makes {string} chargeback with {double} EUR transaction amount for Payment nr. {double}")
|
||||
public void makeLoanChargebackForPayment(String repaymentType, double transactionAmount, double paymentNr) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute();
|
||||
List<GetLoansLoanIdTransactions> transactions = loanDetails.body().getTransactions();
|
||||
|
||||
List<Long> transactionIdList = new ArrayList<>();
|
||||
for (GetLoansLoanIdTransactions f : transactions) {
|
||||
String code = f.getType().getCode();
|
||||
if (code.equals("loanTransactionType.repayment")) {
|
||||
transactionIdList.add(f.getId());
|
||||
}
|
||||
}
|
||||
Collections.sort(transactionIdList);
|
||||
Long transactionId = transactionIdList.get((int) paymentNr - 1);
|
||||
|
||||
makeChargebackCall(loanId, transactionId, repaymentType, transactionAmount);
|
||||
}
|
||||
|
||||
@When("Admin makes {string} chargeback with {double} EUR transaction amount for Downpayment nr. {double}")
|
||||
public void makeLoanChargebackForDownpaymentayment(String repaymentType, double transactionAmount, double paymentNr)
|
||||
throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute();
|
||||
List<GetLoansLoanIdTransactions> transactions = loanDetails.body().getTransactions();
|
||||
|
||||
List<Long> transactionIdList = new ArrayList<>();
|
||||
for (GetLoansLoanIdTransactions f : transactions) {
|
||||
String code = f.getType().getCode();
|
||||
if (code.equals("loanTransactionType.downPayment")) {
|
||||
transactionIdList.add(f.getId());
|
||||
}
|
||||
}
|
||||
Collections.sort(transactionIdList);
|
||||
Long transactionId = transactionIdList.get((int) paymentNr - 1);
|
||||
|
||||
makeChargebackCall(loanId, transactionId, repaymentType, transactionAmount);
|
||||
}
|
||||
|
||||
private void makeChargebackCall(Long loanId, Long transactionId, String repaymentType, double transactionAmount) throws IOException {
|
||||
DefaultPaymentType paymentType = DefaultPaymentType.valueOf(repaymentType);
|
||||
Long paymentTypeValue = paymentTypeResolver.resolve(paymentType);
|
||||
|
||||
PostLoansLoanIdTransactionsTransactionIdRequest chargebackRequest = LoanRequestFactory.defaultChargebackRequest()
|
||||
.paymentTypeId(paymentTypeValue).transactionAmount(transactionAmount);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> chargebackResponse = loanTransactionsApi
|
||||
.adjustLoanTransaction(loanId, transactionId, chargebackRequest, "chargeback").execute();
|
||||
testContext().set(TestContextKey.LOAN_CHARGEBACK_RESPONSE, chargebackResponse);
|
||||
ErrorHelper.checkSuccessfulApiCall(chargebackResponse);
|
||||
|
||||
checkEvents(chargebackResponse);
|
||||
}
|
||||
|
||||
private void checkEvents(Response<PostLoansLoanIdTransactionsResponse> chargebackResponse) throws IOException {
|
||||
PostLoansLoanIdTransactionsResponse responseBody = chargebackResponse.body();
|
||||
Long loanId = responseBody.getLoanId();
|
||||
|
||||
eventAssertion.assertEvent(LoanBalanceChangedEvent.class, loanId).extractingData(data -> data.getId()).isEqualTo(loanId);
|
||||
|
||||
checkLoanChargebackTransactionEvent(responseBody);
|
||||
}
|
||||
|
||||
private void checkLoanChargebackTransactionEvent(PostLoansLoanIdTransactionsResponse chargebackResponse) throws IOException {
|
||||
|
||||
// get loanId and transactionId
|
||||
Long loanId = chargebackResponse.getLoanId();
|
||||
long transactionId = Long.valueOf(chargebackResponse.getResourceId());
|
||||
|
||||
// retrieve transaction details
|
||||
Response<GetLoansLoanIdTransactionsTransactionIdResponse> transactionResponse = loanTransactionsApi
|
||||
.retrieveTransaction(loanId, transactionId, "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(transactionResponse);
|
||||
|
||||
GetLoansLoanIdTransactionsTransactionIdResponse transactionResponseBody = transactionResponse.body();
|
||||
|
||||
// Get transaction type from response
|
||||
GetLoansType transactionType = transactionResponseBody.getType();
|
||||
// Build expected avro transaction type from api response type
|
||||
LoanTransactionEnumDataV1 expectedEventTransactionType = LoanTransactionEnumDataV1.newBuilder()
|
||||
.setId(transactionType.getId().intValue()).setCode(transactionType.getCode()).setValue("Chargeback")
|
||||
.setDisbursement(transactionType.getDisbursement()).setRepaymentAtDisbursement(transactionType.getRepaymentAtDisbursement())
|
||||
.setRepayment(transactionType.getRepayment()).setMerchantIssuedRefund(false).setPayoutRefund(false).setGoodwillCredit(false)
|
||||
.setChargeRefund(false).setContra(transactionType.getContra()).setWaiveInterest(transactionType.getWaiveInterest())
|
||||
.setWaiveCharges(transactionType.getWaiveCharges()).setAccrual(false).setWriteOff(transactionType.getWriteOff())
|
||||
.setRecoveryRepayment(transactionType.getRecoveryRepayment()).setInitiateTransfer(false).setApproveTransfer(false)
|
||||
.setWithdrawTransfer(false).setRejectTransfer(false).setChargePayment(false).setRefund(false).setRefundForActiveLoans(false)
|
||||
.setCreditBalanceRefund(false).setChargeback(true).build();
|
||||
|
||||
// verify payload for loanId, transactionId, transactionType, amount
|
||||
eventAssertion.assertEvent(LoanChargebackTransactionEvent.class, transactionId).extractingData(LoanTransactionDataV1::getLoanId)
|
||||
.isEqualTo(loanId).extractingData(LoanTransactionDataV1::getType).isEqualTo(expectedEventTransactionType)
|
||||
.extractingBigDecimal(LoanTransactionDataV1::getAmount).isEqualTo(BigDecimal.valueOf(transactionResponseBody.getAmount()));
|
||||
|
||||
}
|
||||
}
|
||||
+296
@@ -0,0 +1,296 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.loan;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.cucumber.datatable.DataTable;
|
||||
import io.cucumber.java.en.And;
|
||||
import io.cucumber.java.en.Then;
|
||||
import io.cucumber.java.en.When;
|
||||
import java.io.IOException;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.avro.loan.v1.LoanChargeDataV1;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdChargesChargeIdResponse;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdTransactions;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdRequest;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdChargesRequest;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdChargesResponse;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.models.PutChargeTransactionChangesRequest;
|
||||
import org.apache.fineract.client.models.PutChargeTransactionChangesResponse;
|
||||
import org.apache.fineract.client.services.LoanChargesApi;
|
||||
import org.apache.fineract.client.services.LoanTransactionsApi;
|
||||
import org.apache.fineract.client.services.LoansApi;
|
||||
import org.apache.fineract.client.util.JSON;
|
||||
import org.apache.fineract.test.data.ChargeProductType;
|
||||
import org.apache.fineract.test.data.ErrorMessageType;
|
||||
import org.apache.fineract.test.factory.LoanChargeRequestFactory;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.helper.ErrorMessageHelper;
|
||||
import org.apache.fineract.test.helper.ErrorResponse;
|
||||
import org.apache.fineract.test.messaging.EventAssertion;
|
||||
import org.apache.fineract.test.messaging.event.loan.charge.LoanAddChargeEvent;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.apache.fineract.test.support.TestContextKey;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import retrofit2.Response;
|
||||
|
||||
@Slf4j
|
||||
public class LoanChargeStepDef extends AbstractStepDef {
|
||||
|
||||
public static final String DEFAULT_DATE_FORMAT = "dd MMMM yyyy";
|
||||
public static final String DATE_FORMAT_EVENTS = "yyyy-MM-dd";
|
||||
public static final Double DEFAULT_CHARGE_FEE_FLAT = 10D;
|
||||
private static final Gson GSON = new JSON().getGson();
|
||||
|
||||
@Autowired
|
||||
private LoanChargesApi loanChargesApi;
|
||||
@Autowired
|
||||
private LoanTransactionsApi loanTransactionsApi;
|
||||
@Autowired
|
||||
private LoansApi loansApi;
|
||||
@Autowired
|
||||
private EventAssertion eventAssertion;
|
||||
|
||||
@When("Admin adds {string} due date charge with {string} due date and {double} EUR transaction amount")
|
||||
public void addChargeDueDate(String chargeType, String transactionDate, double transactionAmount) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
ChargeProductType chargeProductType = ChargeProductType.valueOf(chargeType);
|
||||
Long chargeTypeId = chargeProductType.getValue();
|
||||
if (chargeTypeId.equals(ChargeProductType.LOAN_DISBURSEMENT_PERCENTAGE_FEE.getValue())
|
||||
|| chargeTypeId.equals(ChargeProductType.LOAN_TRANCHE_DISBURSEMENT_PERCENTAGE_FEE.getValue())
|
||||
|| chargeTypeId.equals(ChargeProductType.LOAN_INSTALLMENT_PERCENTAGE_FEE.getValue())) {
|
||||
throw new IllegalStateException(String.format("The requested %s charge is NOT due date type, cannot be used here", chargeType));
|
||||
}
|
||||
|
||||
PostLoansLoanIdChargesRequest loanIdChargesRequest = LoanChargeRequestFactory.defaultLoanChargeRequest().chargeId(chargeTypeId)
|
||||
.dueDate(transactionDate).amount(transactionAmount);
|
||||
|
||||
Response<PostLoansLoanIdChargesResponse> loanChargeResponse = loanChargesApi.executeLoanCharge(loanId, loanIdChargesRequest, "")
|
||||
.execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanChargeResponse);
|
||||
testContext().set(TestContextKey.ADD_DUE_DATE_CHARGE_RESPONSE, loanChargeResponse);
|
||||
|
||||
addChargeEventCheck(loanChargeResponse);
|
||||
}
|
||||
|
||||
@When("Admin adds {string} charge with {double} % of transaction amount")
|
||||
public void addChargePercentage(String chargeType, double transactionPercentageAmount) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
ChargeProductType chargeProductType = ChargeProductType.valueOf(chargeType);
|
||||
Long chargeTypeId = chargeProductType.getValue();
|
||||
if (!chargeTypeId.equals(ChargeProductType.LOAN_DISBURSEMENT_PERCENTAGE_FEE.getValue())
|
||||
&& !chargeTypeId.equals(ChargeProductType.LOAN_TRANCHE_DISBURSEMENT_PERCENTAGE_FEE.getValue())
|
||||
&& !chargeTypeId.equals(ChargeProductType.LOAN_INSTALLMENT_PERCENTAGE_FEE.getValue())) {
|
||||
throw new IllegalStateException(String.format("The requested %s charge is due date type, cannot be used here", chargeType));
|
||||
}
|
||||
|
||||
PostLoansLoanIdChargesRequest loanIdChargesRequest = LoanChargeRequestFactory.defaultLoanChargeRequest().chargeId(chargeTypeId)
|
||||
.amount(transactionPercentageAmount);
|
||||
|
||||
Response<PostLoansLoanIdChargesResponse> loanChargeResponse = loanChargesApi.executeLoanCharge(loanId, loanIdChargesRequest, "")
|
||||
.execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanChargeResponse);
|
||||
testContext().set(TestContextKey.ADD_DUE_DATE_CHARGE_RESPONSE, loanChargeResponse);
|
||||
}
|
||||
|
||||
@Then("Admin is not able to add {string} due date charge with {string} due date and {double} EUR transaction amount because the of charged-off account")
|
||||
public void addChargeDueDateOnChargedOff(String chargeType, String transactionDate, double transactionAmount) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
ChargeProductType chargeProductType = ChargeProductType.valueOf(chargeType);
|
||||
Long chargeTypeId = chargeProductType.getValue();
|
||||
|
||||
PostLoansLoanIdChargesRequest loanIdChargesRequest = LoanChargeRequestFactory.defaultLoanChargeRequest().chargeId(chargeTypeId)
|
||||
.dueDate(transactionDate).amount(transactionAmount);
|
||||
|
||||
Response<PostLoansLoanIdChargesResponse> loanChargeResponse = loanChargesApi.executeLoanCharge(loanId, loanIdChargesRequest, "")
|
||||
.execute();
|
||||
testContext().set(TestContextKey.ADD_DUE_DATE_CHARGE_RESPONSE, loanChargeResponse);
|
||||
ErrorResponse errorDetails = ErrorResponse.from(loanChargeResponse);
|
||||
assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.addChargeForChargeOffLoanCodeMsg()).isEqualTo(403);
|
||||
assertThat(errorDetails.getSingleError().getDeveloperMessage())
|
||||
.isEqualTo(ErrorMessageHelper.addChargeForChargeOffLoanFailure(loanId));
|
||||
}
|
||||
|
||||
@And("Admin adds a {double} % Processing charge to the loan with {string} locale on date: {string}")
|
||||
public void addProcessingFee(double chargeAmount, String locale, String date) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
PostLoansLoanIdChargesRequest loanIdChargesRequest = LoanChargeRequestFactory.defaultLoanChargeRequest()
|
||||
.chargeId(ChargeProductType.LOAN_PERCENTAGE_PROCESSING_FEE.value).amount(chargeAmount).dueDate(date)
|
||||
.dateFormat(DEFAULT_DATE_FORMAT).locale(locale);
|
||||
|
||||
Response<PostLoansLoanIdChargesResponse> loanChargeResponse = loanChargesApi.executeLoanCharge(loanId, loanIdChargesRequest, "")
|
||||
.execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanChargeResponse);
|
||||
testContext().set(TestContextKey.ADD_PROCESSING_FEE_RESPONSE, loanChargeResponse);
|
||||
}
|
||||
|
||||
@And("Admin adds an NSF fee because of payment bounce with {string} transaction date")
|
||||
public void addNSFfee(String date) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
PostLoansLoanIdChargesRequest loanIdChargesRequest = LoanChargeRequestFactory.defaultLoanChargeRequest()
|
||||
.chargeId(ChargeProductType.LOAN_NSF_FEE.value).amount(DEFAULT_CHARGE_FEE_FLAT).dueDate(date)
|
||||
.dateFormat(DEFAULT_DATE_FORMAT);
|
||||
|
||||
Response<PostLoansLoanIdChargesResponse> loanChargeResponse = loanChargesApi.executeLoanCharge(loanId, loanIdChargesRequest, "")
|
||||
.execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanChargeResponse);
|
||||
testContext().set(TestContextKey.ADD_NSF_FEE_RESPONSE, loanChargeResponse);
|
||||
}
|
||||
|
||||
@And("Admin waives charge")
|
||||
public void waiveCharge() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<PostLoansLoanIdChargesResponse> loanChargeResponse = testContext().get(TestContextKey.ADD_NSF_FEE_RESPONSE);
|
||||
Long chargeId = Long.valueOf(loanChargeResponse.body().getResourceId());
|
||||
|
||||
PostLoansLoanIdChargesChargeIdRequest waiveRequest = new PostLoansLoanIdChargesChargeIdRequest();
|
||||
|
||||
Response<PostLoansLoanIdChargesChargeIdResponse> waiveResponse = loanChargesApi
|
||||
.executeLoanCharge2(loanId, chargeId, waiveRequest, "waive").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(waiveResponse);
|
||||
testContext().set(TestContextKey.WAIVE_CHARGE_RESPONSE, waiveResponse);
|
||||
}
|
||||
|
||||
@And("Admin waives due date charge")
|
||||
public void waiveDueDateCharge() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<PostLoansLoanIdChargesResponse> loanChargeResponse = testContext().get(TestContextKey.ADD_DUE_DATE_CHARGE_RESPONSE);
|
||||
Long chargeId = Long.valueOf(loanChargeResponse.body().getResourceId());
|
||||
|
||||
PostLoansLoanIdChargesChargeIdRequest waiveRequest = new PostLoansLoanIdChargesChargeIdRequest();
|
||||
|
||||
Response<PostLoansLoanIdChargesChargeIdResponse> waiveResponse = loanChargesApi
|
||||
.executeLoanCharge2(loanId, chargeId, waiveRequest, "waive").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(waiveResponse);
|
||||
testContext().set(TestContextKey.WAIVE_CHARGE_RESPONSE, waiveResponse);
|
||||
}
|
||||
|
||||
@And("Admin makes waive undone for charge")
|
||||
public void undoWaiveForCharge() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute();
|
||||
List<GetLoansLoanIdTransactions> transactions = loanDetails.body().getTransactions();
|
||||
|
||||
Long transactionId = 0L;
|
||||
for (GetLoansLoanIdTransactions f : transactions) {
|
||||
String code = f.getType().getCode();
|
||||
if (code.equals("loanTransactionType.waiveCharges")) {
|
||||
transactionId = f.getId();
|
||||
}
|
||||
}
|
||||
|
||||
PutChargeTransactionChangesRequest undoWaiveRequest = new PutChargeTransactionChangesRequest();
|
||||
Response<PutChargeTransactionChangesResponse> undoWaiveResponse = loanTransactionsApi
|
||||
.undoWaiveCharge(loanId, transactionId, undoWaiveRequest).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(undoWaiveResponse);
|
||||
testContext().set(TestContextKey.UNDO_WAIVE_RESPONSE, undoWaiveResponse);
|
||||
}
|
||||
|
||||
@Then("Charge is successfully added to the loan")
|
||||
public void loanChargeStatus() throws IOException {
|
||||
Response<PostLoansLoanIdChargesResponse> response = testContext().get(TestContextKey.ADD_NSF_FEE_RESPONSE);
|
||||
|
||||
assertThat(response.isSuccessful()).as(ErrorMessageHelper.requestFailed(response)).isTrue();
|
||||
assertThat(response.code()).as(ErrorMessageHelper.requestFailedWithCode(response)).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Then("Charge is successfully added to the loan with {float} EUR")
|
||||
public void checkLoanChargeAmount(float chargeAmount) throws IOException {
|
||||
Response<PostLoansLoanIdChargesResponse> response = testContext().get(TestContextKey.ADD_PROCESSING_FEE_RESPONSE);
|
||||
Response<GetLoansLoanIdChargesChargeIdResponse> loanChargeAmount = loanChargesApi
|
||||
.retrieveLoanCharge(response.body().getLoanId(), Long.valueOf(response.body().getResourceId())).execute();
|
||||
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
assertThat(loanChargeAmount.body().getAmount()).as("Charge amount is wrong").isEqualTo(chargeAmount);
|
||||
}
|
||||
|
||||
private void addChargeEventCheck(Response<PostLoansLoanIdChargesResponse> loanChargeResponse) throws IOException {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT_EVENTS);
|
||||
Response<GetLoansLoanIdChargesChargeIdResponse> chargeDetails = loanChargesApi
|
||||
.retrieveLoanCharge(loanChargeResponse.body().getLoanId(), loanChargeResponse.body().getResourceId()).execute();
|
||||
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()));
|
||||
}
|
||||
|
||||
@Then("Loan charge transaction with the following data results a {int} error and {string} error message")
|
||||
public void chargeOffTransactionError(int errorCodeExpected, String errorMessageType, DataTable table) throws IOException {
|
||||
List<List<String>> data = table.asLists();
|
||||
List<String> chargeData = data.get(1);
|
||||
String chargeType = chargeData.get(0);
|
||||
String transactionDate = chargeData.get(1);
|
||||
Double transactionAmount = Double.valueOf(chargeData.get(2));
|
||||
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
ErrorMessageType errorMsgType = ErrorMessageType.valueOf(errorMessageType);
|
||||
String errorMessageExpectedRaw = errorMsgType.getValue();
|
||||
String errorMessageExpected = String.format(errorMessageExpectedRaw, loanId);
|
||||
|
||||
ChargeProductType chargeProductType = ChargeProductType.valueOf(chargeType);
|
||||
Long chargeTypeId = chargeProductType.getValue();
|
||||
if (chargeTypeId.equals(ChargeProductType.LOAN_DISBURSEMENT_PERCENTAGE_FEE.getValue())
|
||||
|| chargeTypeId.equals(ChargeProductType.LOAN_TRANCHE_DISBURSEMENT_PERCENTAGE_FEE.getValue())
|
||||
|| chargeTypeId.equals(ChargeProductType.LOAN_INSTALLMENT_PERCENTAGE_FEE.getValue())) {
|
||||
throw new IllegalStateException(String.format("The requested %s charge is NOT due date type, cannot be used here", chargeType));
|
||||
}
|
||||
|
||||
PostLoansLoanIdChargesRequest loanIdChargesRequest = LoanChargeRequestFactory.defaultLoanChargeRequest().chargeId(chargeTypeId)
|
||||
.dueDate(transactionDate).amount(transactionAmount);
|
||||
|
||||
Response<PostLoansLoanIdChargesResponse> loanChargeResponse = loanChargesApi.executeLoanCharge(loanId, loanIdChargesRequest, "")
|
||||
.execute();
|
||||
int errorCodeActual = loanChargeResponse.code();
|
||||
String errorBody = loanChargeResponse.errorBody().string();
|
||||
ErrorResponse errorResponse = GSON.fromJson(errorBody, ErrorResponse.class);
|
||||
String errorMessageActual = errorResponse.getErrors().get(0).getDeveloperMessage();
|
||||
|
||||
assertThat(errorCodeActual).as(ErrorMessageHelper.wrongErrorCode(errorCodeActual, errorCodeExpected)).isEqualTo(errorCodeExpected);
|
||||
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
|
||||
.isEqualTo(errorMessageExpected);
|
||||
|
||||
log.info("ERROR CODE: {}", errorCodeActual);
|
||||
log.info("ERROR MESSAGE: {}", errorMessageActual);
|
||||
}
|
||||
}
|
||||
+771
@@ -0,0 +1,771 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.loan;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import io.cucumber.datatable.DataTable;
|
||||
import io.cucumber.java.en.Then;
|
||||
import io.cucumber.java.en.When;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.fineract.avro.loan.v1.LoanAccountDelinquencyRangeDataV1;
|
||||
import org.apache.fineract.avro.loan.v1.LoanInstallmentDelinquencyBucketDataV1;
|
||||
import org.apache.fineract.client.models.GetDelinquencyActionsResponse;
|
||||
import org.apache.fineract.client.models.GetDelinquencyRangesResponse;
|
||||
import org.apache.fineract.client.models.GetDelinquencyTagHistoryResponse;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdDelinquencyPausePeriod;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdDelinquencySummary;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdLoanInstallmentLevelDelinquency;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.GetUsersUserIdResponse;
|
||||
import org.apache.fineract.client.models.PostLoansDelinquencyActionRequest;
|
||||
import org.apache.fineract.client.models.PostLoansDelinquencyActionResponse;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.models.PostUsersResponse;
|
||||
import org.apache.fineract.client.services.LoansApi;
|
||||
import org.apache.fineract.client.services.UsersApi;
|
||||
import org.apache.fineract.client.util.JSON;
|
||||
import org.apache.fineract.test.api.ApiProperties;
|
||||
import org.apache.fineract.test.data.DelinquencyRange;
|
||||
import org.apache.fineract.test.data.LoanStatus;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.helper.ErrorMessageHelper;
|
||||
import org.apache.fineract.test.helper.ErrorResponse;
|
||||
import org.apache.fineract.test.messaging.EventAssertion;
|
||||
import org.apache.fineract.test.messaging.event.EventCheckHelper;
|
||||
import org.apache.fineract.test.messaging.event.loan.delinquency.LoanDelinquencyRangeChangeEvent;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.apache.fineract.test.support.TestContextKey;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import retrofit2.Response;
|
||||
|
||||
@Slf4j
|
||||
public class LoanDelinquencyStepDef extends AbstractStepDef {
|
||||
|
||||
public static final String DATE_FORMAT = "dd MMMM yyyy";
|
||||
public static final String DEFAULT_LOCALE = "en";
|
||||
public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(DATE_FORMAT);
|
||||
private static final Gson GSON = new JSON().getGson();
|
||||
|
||||
@Autowired
|
||||
private LoansApi loansApi;
|
||||
|
||||
@Autowired
|
||||
private EventAssertion eventAssertion;
|
||||
|
||||
@Autowired
|
||||
private EventCheckHelper eventCheckHelper;
|
||||
|
||||
@Autowired
|
||||
private ApiProperties apiProperties;
|
||||
|
||||
@Autowired
|
||||
private UsersApi usersApi;
|
||||
|
||||
@Then("Admin checks that delinquency range is: {string} and has delinquentDate {string}")
|
||||
public void checkDelinquencyRange(String range, String delinquentDateExpected) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetails);
|
||||
Integer loanStatus = loanDetails.body().getStatus().getId();
|
||||
|
||||
if (!LoanStatus.SUBMITTED_AND_PENDING_APPROVAL.value.equals(loanStatus) && !LoanStatus.APPROVED.value.equals(loanStatus)) {
|
||||
String delinquentDateExpectedValue = "".equals(delinquentDateExpected) ? null : delinquentDateExpected;
|
||||
eventAssertion.assertEvent(LoanDelinquencyRangeChangeEvent.class, loanId)//
|
||||
.extractingData(LoanAccountDelinquencyRangeDataV1::getDelinquentDate)//
|
||||
.isEqualTo(delinquentDateExpectedValue);//
|
||||
}
|
||||
|
||||
DelinquencyRange expectedDelinquencyRange = DelinquencyRange.valueOf(range);
|
||||
String expectedDelinquencyRangeValue = expectedDelinquencyRange.getValue();
|
||||
|
||||
String actualDelinquencyRangeValue = DelinquencyRange.NO_DELINQUENCY.value;
|
||||
GetDelinquencyRangesResponse actualDelinquencyRange = loanDetails.body().getDelinquencyRange();
|
||||
if (actualDelinquencyRange != null) {
|
||||
actualDelinquencyRangeValue = actualDelinquencyRange.getClassification();
|
||||
}
|
||||
|
||||
assertThat(actualDelinquencyRangeValue)
|
||||
.as(ErrorMessageHelper.delinquencyRangeError(actualDelinquencyRangeValue, expectedDelinquencyRangeValue))
|
||||
.isEqualTo(expectedDelinquencyRangeValue);
|
||||
}
|
||||
|
||||
@Then("Admin checks that {string}th delinquency range is: {string} and added on: {string} and has delinquentDate {string}")
|
||||
public void checkDelinquencyRange(String nthInList, String range, String addedOnDate, String delinquentDateExpected)
|
||||
throws IOException {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
String delinquentDateExpectedValue = "".equals(delinquentDateExpected) ? null : delinquentDateExpected;
|
||||
eventAssertion.assertEvent(LoanDelinquencyRangeChangeEvent.class, loanId)
|
||||
.extractingData(LoanAccountDelinquencyRangeDataV1::getDelinquentDate).isEqualTo(delinquentDateExpectedValue);
|
||||
|
||||
DelinquencyRange expectedDelinquencyRange = DelinquencyRange.valueOf(range);
|
||||
String expectedDelinquencyRangeValue = expectedDelinquencyRange.getValue();
|
||||
|
||||
Response<List<GetDelinquencyTagHistoryResponse>> delinquencyHistoryDetails = loansApi.getDelinquencyTagHistory(loanId).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(delinquencyHistoryDetails);
|
||||
|
||||
String actualDelinquencyRangeValue = DelinquencyRange.NO_DELINQUENCY.value;
|
||||
String actualDelinquencyAddedOnDate = "";
|
||||
int i = Integer.parseInt(nthInList) - 1;
|
||||
GetDelinquencyTagHistoryResponse delinquencyTag = delinquencyHistoryDetails.body().get(i);
|
||||
if (delinquencyTag != null) {
|
||||
actualDelinquencyRangeValue = delinquencyTag.getDelinquencyRange().getClassification();
|
||||
actualDelinquencyAddedOnDate = formatter.format(delinquencyTag.getAddedOnDate());
|
||||
}
|
||||
|
||||
assertThat(actualDelinquencyRangeValue)
|
||||
.as(ErrorMessageHelper.delinquencyRangeError(actualDelinquencyRangeValue, expectedDelinquencyRangeValue))
|
||||
.isEqualTo(expectedDelinquencyRangeValue);
|
||||
assertThat(actualDelinquencyAddedOnDate).as(ErrorMessageHelper.delinquencyRangeError(actualDelinquencyAddedOnDate, addedOnDate))
|
||||
.isEqualTo(addedOnDate);
|
||||
}
|
||||
|
||||
@Then("Loan delinquency history has the following details:")
|
||||
public void delinquencyHistoryCheck(DataTable table) throws IOException {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
|
||||
List<List<String>> dataExpected = table.asLists();
|
||||
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<List<GetDelinquencyTagHistoryResponse>> delinquencyHistoryDetails = loansApi.getDelinquencyTagHistory(loanId).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(delinquencyHistoryDetails);
|
||||
List<GetDelinquencyTagHistoryResponse> body = delinquencyHistoryDetails.body();
|
||||
|
||||
for (int i = 0; i < body.size(); i++) {
|
||||
List<String> line = dataExpected.get(i + 1);
|
||||
DelinquencyRange expectedDelinquencyRange = DelinquencyRange.valueOf(line.get(0));
|
||||
String classificationExpected = expectedDelinquencyRange.getValue();
|
||||
String addedOnDateExpected = line.get(1);
|
||||
String liftedOnDateExpected = line.get(2);
|
||||
|
||||
String classificationActual = body.get(i).getDelinquencyRange().getClassification();
|
||||
String addedOnDateActual = body.get(i).getAddedOnDate() == null ? null : formatter.format(body.get(i).getAddedOnDate());
|
||||
String liftedOnDateActual = body.get(i).getLiftedOnDate() == null ? null : formatter.format(body.get(i).getLiftedOnDate());
|
||||
|
||||
assertThat(classificationActual)
|
||||
.as(ErrorMessageHelper.wrongDataInDelinquencyHistoryClassification(classificationActual, classificationExpected))
|
||||
.isEqualTo(classificationExpected);
|
||||
assertThat(addedOnDateActual)
|
||||
.as(ErrorMessageHelper.wrongDataInDelinquencyHistoryAddedOnDate(addedOnDateActual, addedOnDateExpected))
|
||||
.isEqualTo(addedOnDateExpected);
|
||||
assertThat(liftedOnDateActual)
|
||||
.as(ErrorMessageHelper.wrongDataInDelinquencyHistoryLiftedOnDate(liftedOnDateActual, liftedOnDateExpected))
|
||||
.isEqualTo(liftedOnDateExpected);
|
||||
}
|
||||
}
|
||||
|
||||
@When("Admin initiate a DELINQUENCY PAUSE with startDate: {string} and endDate: {string}")
|
||||
public void delinquencyPause(String startDate, String endDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostLoansDelinquencyActionRequest request = new PostLoansDelinquencyActionRequest()//
|
||||
.action("pause")//
|
||||
.startDate(startDate)//
|
||||
.endDate(endDate)//
|
||||
.dateFormat(DATE_FORMAT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostLoansDelinquencyActionResponse> response = loansApi.createLoanDelinquencyAction(loanId, request).execute();
|
||||
testContext().set(TestContextKey.LOAN_DELINQUENCY_ACTION_RESPONSE, response);
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
eventCheckHelper.loanAccountDelinquencyPauseChangedBusinessEventCheck(loanId);
|
||||
}
|
||||
|
||||
@When("Created user with CREATE_DELINQUENCY_ACTION permission initiate a DELINQUENCY PAUSE with startDate: {string} and endDate: {string}")
|
||||
public void delinquencyPauseWithCreatedUser(String startDate, String endDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostLoansDelinquencyActionRequest request = new PostLoansDelinquencyActionRequest()//
|
||||
.action("pause")//
|
||||
.startDate(startDate)//
|
||||
.endDate(endDate)//
|
||||
.dateFormat(DATE_FORMAT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Map<String, String> headerMap = new HashMap<>();
|
||||
Response<PostUsersResponse> createUserResponse = testContext().get(TestContextKey.CREATED_SIMPLE_USER_RESPONSE);
|
||||
Long createdUserId = createUserResponse.body().getResourceId();
|
||||
Response<GetUsersUserIdResponse> user = usersApi.retrieveOne31(createdUserId).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(user);
|
||||
String authorizationString = user.body().getUsername() + ":" + apiProperties.getPassword();
|
||||
Base64 base64 = new Base64();
|
||||
headerMap.put("Authorization",
|
||||
"Basic " + new String(base64.encode(authorizationString.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));
|
||||
|
||||
Response<PostLoansDelinquencyActionResponse> response = loansApi.createLoanDelinquencyAction(loanId, request, headerMap).execute();
|
||||
testContext().set(TestContextKey.LOAN_DELINQUENCY_ACTION_RESPONSE, response);
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
eventCheckHelper.loanAccountDelinquencyPauseChangedBusinessEventCheck(loanId);
|
||||
}
|
||||
|
||||
@Then("Created user with no CREATE_DELINQUENCY_ACTION permission gets an error when initiate a DELINQUENCY PAUSE with startDate: {string} and endDate: {string}")
|
||||
public void delinquencyPauseWithCreatedUserNOPermissionError(String startDate, String endDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
int errorCodeExpected = 403;
|
||||
String errorMessageExpected = "User has no authority to CREATE delinquency_actions";
|
||||
|
||||
PostLoansDelinquencyActionRequest request = new PostLoansDelinquencyActionRequest()//
|
||||
.action("pause")//
|
||||
.startDate(startDate)//
|
||||
.endDate(endDate)//
|
||||
.dateFormat(DATE_FORMAT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Map<String, String> headerMap = new HashMap<>();
|
||||
Response<PostUsersResponse> createUserResponse = testContext().get(TestContextKey.CREATED_SIMPLE_USER_RESPONSE);
|
||||
Long createdUserId = createUserResponse.body().getResourceId();
|
||||
Response<GetUsersUserIdResponse> user = usersApi.retrieveOne31(createdUserId).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(user);
|
||||
String authorizationString = user.body().getUsername() + ":" + apiProperties.getPassword();
|
||||
Base64 base64 = new Base64();
|
||||
headerMap.put("Authorization",
|
||||
"Basic " + new String(base64.encode(authorizationString.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));
|
||||
|
||||
Response<PostLoansDelinquencyActionResponse> response = loansApi.createLoanDelinquencyAction(loanId, request, headerMap).execute();
|
||||
testContext().set(TestContextKey.LOAN_DELINQUENCY_ACTION_RESPONSE, response);
|
||||
int errorCodeActual = response.code();
|
||||
String errorBody = response.errorBody().string();
|
||||
ErrorResponse errorResponse = GSON.fromJson(errorBody, ErrorResponse.class);
|
||||
String errorMessageActual = errorResponse.getErrors().get(0).getDeveloperMessage();
|
||||
|
||||
assertThat(errorCodeActual).as(ErrorMessageHelper.wrongErrorCode(errorCodeActual, errorCodeExpected)).isEqualTo(errorCodeExpected);
|
||||
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
|
||||
.isEqualTo(errorMessageExpected);
|
||||
|
||||
log.info("ERROR CODE: {}", errorCodeActual);
|
||||
log.info("ERROR MESSAGE: {}", errorMessageActual);
|
||||
}
|
||||
|
||||
@When("Admin initiate a DELINQUENCY RESUME with startDate: {string}")
|
||||
public void delinquencyResume(String startDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostLoansDelinquencyActionRequest request = new PostLoansDelinquencyActionRequest()//
|
||||
.action("resume")//
|
||||
.startDate(startDate)//
|
||||
.dateFormat(DATE_FORMAT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostLoansDelinquencyActionResponse> response = loansApi.createLoanDelinquencyAction(loanId, request).execute();
|
||||
testContext().set(TestContextKey.LOAN_DELINQUENCY_ACTION_RESPONSE, response);
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
eventCheckHelper.loanAccountDelinquencyPauseChangedBusinessEventCheck(loanId);
|
||||
}
|
||||
|
||||
@When("Admin initiate a DELINQUENCY PAUSE by loanExternalId with startDate: {string} and endDate: {string}")
|
||||
public void delinquencyPauseByLoanExternalId(String startDate, String endDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
String loanExternalId = loanResponse.body().getResourceExternalId();
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostLoansDelinquencyActionRequest request = new PostLoansDelinquencyActionRequest()//
|
||||
.action("pause")//
|
||||
.startDate(startDate)//
|
||||
.endDate(endDate)//
|
||||
.dateFormat(DATE_FORMAT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostLoansDelinquencyActionResponse> response = loansApi.createLoanDelinquencyAction1(loanExternalId, request).execute();
|
||||
testContext().set(TestContextKey.LOAN_DELINQUENCY_ACTION_RESPONSE, response);
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
eventCheckHelper.loanAccountDelinquencyPauseChangedBusinessEventCheck(loanId);
|
||||
}
|
||||
|
||||
@When("Admin initiate a DELINQUENCY RESUME by loanExternalId with startDate: {string}")
|
||||
public void delinquencyResumeByLoanExternalId(String startDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
String loanExternalId = loanResponse.body().getResourceExternalId();
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostLoansDelinquencyActionRequest request = new PostLoansDelinquencyActionRequest()//
|
||||
.action("resume")//
|
||||
.startDate(startDate)//
|
||||
.dateFormat(DATE_FORMAT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostLoansDelinquencyActionResponse> response = loansApi.createLoanDelinquencyAction1(loanExternalId, request).execute();
|
||||
testContext().set(TestContextKey.LOAN_DELINQUENCY_ACTION_RESPONSE, response);
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
eventCheckHelper.loanAccountDelinquencyPauseChangedBusinessEventCheck(loanId);
|
||||
}
|
||||
|
||||
@Then("Delinquency-actions have the following data:")
|
||||
public void getDelinquencyActionData(DataTable table) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
List<List<String>> data = table.asLists();
|
||||
int nrOfLinesExpected = data.size() - 1;
|
||||
|
||||
Response<List<GetDelinquencyActionsResponse>> response = loansApi.getLoanDelinquencyActions(loanId).execute();
|
||||
int nrOfLinesActual = response.body().size();
|
||||
|
||||
assertThat(nrOfLinesActual)//
|
||||
.as(ErrorMessageHelper.wrongNumberOfLinesInDelinquencyActions(nrOfLinesActual, nrOfLinesExpected))//
|
||||
.isEqualTo(nrOfLinesExpected);//
|
||||
|
||||
for (int i = 1; i < data.size(); i++) {
|
||||
List<String> expectedValues = data.get(i);
|
||||
|
||||
GetDelinquencyActionsResponse lineActual = response.body().get(i - 1);
|
||||
|
||||
List<String> actualValues = new ArrayList<>();
|
||||
actualValues.add(Objects.requireNonNull(lineActual.getAction()));
|
||||
actualValues.add(FORMATTER.format(Objects.requireNonNull(lineActual.getStartDate())));
|
||||
actualValues.add(lineActual.getEndDate() == null ? null : FORMATTER.format(lineActual.getEndDate()));
|
||||
|
||||
assertThat(actualValues)//
|
||||
.as(ErrorMessageHelper.wrongValueInLineDelinquencyActions(i, actualValues, expectedValues))//
|
||||
.isEqualTo(expectedValues);//
|
||||
}
|
||||
}
|
||||
|
||||
@Then("Initiating a delinquency-action other than PAUSE or RESUME in action field results an error - startDate: {string}, endDate: {string}")
|
||||
public void actionFieldError(String startDate, String endDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostLoansDelinquencyActionRequest request = new PostLoansDelinquencyActionRequest()//
|
||||
.action("TEST")//
|
||||
.startDate(startDate)//
|
||||
.endDate(endDate)//
|
||||
.dateFormat(DATE_FORMAT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostLoansDelinquencyActionResponse> response = loansApi.createLoanDelinquencyAction(loanId, request).execute();
|
||||
int errorCodeExpected = 400;
|
||||
String errorMessageExpected = "Invalid Delinquency Action: TEST";
|
||||
errorMessageAssertation(response, errorCodeExpected, errorMessageExpected);
|
||||
}
|
||||
|
||||
@Then("Initiating a DELINQUENCY PAUSE with startDate before the actual business date results an error - startDate: {string}, endDate: {string}")
|
||||
public void delinquencyPauseStartDateError(String startDate, String endDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostLoansDelinquencyActionRequest request = new PostLoansDelinquencyActionRequest()//
|
||||
.action("pause")//
|
||||
.startDate(startDate)//
|
||||
.endDate(endDate)//
|
||||
.dateFormat(DATE_FORMAT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostLoansDelinquencyActionResponse> response = loansApi.createLoanDelinquencyAction(loanId, request).execute();
|
||||
int errorCodeExpected = 400;
|
||||
String errorMessageExpected = "Start date of pause period must be in the future";
|
||||
errorMessageAssertation(response, errorCodeExpected, errorMessageExpected);
|
||||
}
|
||||
|
||||
@Then("Initiating a DELINQUENCY PAUSE on a non-active loan results an error - startDate: {string}, endDate: {string}")
|
||||
public void delinquencyPauseNonActiveLoanError(String startDate, String endDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostLoansDelinquencyActionRequest request = new PostLoansDelinquencyActionRequest()//
|
||||
.action("pause")//
|
||||
.startDate(startDate)//
|
||||
.endDate(endDate)//
|
||||
.dateFormat(DATE_FORMAT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostLoansDelinquencyActionResponse> response = loansApi.createLoanDelinquencyAction(loanId, request).execute();
|
||||
int errorCodeExpected = 400;
|
||||
String errorMessageExpected = "Delinquency actions can be created only for active loans.";
|
||||
errorMessageAssertation(response, errorCodeExpected, errorMessageExpected);
|
||||
}
|
||||
|
||||
@Then("Initiating a DELINQUENCY RESUME on a non-active loan results an error - startDate: {string}")
|
||||
public void delinquencyResumeNonActiveLoanError(String startDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostLoansDelinquencyActionRequest request = new PostLoansDelinquencyActionRequest()//
|
||||
.action("resume")//
|
||||
.startDate(startDate)//
|
||||
.dateFormat(DATE_FORMAT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostLoansDelinquencyActionResponse> response = loansApi.createLoanDelinquencyAction(loanId, request).execute();
|
||||
int errorCodeExpected = 400;
|
||||
String errorMessageExpected = "Delinquency actions can be created only for active loans.";
|
||||
errorMessageAssertation(response, errorCodeExpected, errorMessageExpected);
|
||||
}
|
||||
|
||||
@Then("Overlapping PAUSE periods result an error - startDate: {string}, endDate: {string}")
|
||||
public void delinquencyPauseOverlappingError(String startDate, String endDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostLoansDelinquencyActionRequest request = new PostLoansDelinquencyActionRequest()//
|
||||
.action("pause")//
|
||||
.startDate(startDate)//
|
||||
.endDate(endDate)//
|
||||
.dateFormat(DATE_FORMAT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostLoansDelinquencyActionResponse> response = loansApi.createLoanDelinquencyAction(loanId, request).execute();
|
||||
int errorCodeExpected = 400;
|
||||
String errorMessageExpected = "Delinquency pause period cannot overlap with another pause period";
|
||||
errorMessageAssertation(response, errorCodeExpected, errorMessageExpected);
|
||||
}
|
||||
|
||||
@Then("Initiating a DELINQUENCY RESUME without an active PAUSE period results an error - startDate: {string}")
|
||||
public void delinquencyResumeWithoutPauseError(String startDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostLoansDelinquencyActionRequest request = new PostLoansDelinquencyActionRequest()//
|
||||
.action("resume")//
|
||||
.startDate(startDate)//
|
||||
.dateFormat(DATE_FORMAT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostLoansDelinquencyActionResponse> response = loansApi.createLoanDelinquencyAction(loanId, request).execute();
|
||||
int errorCodeExpected = 400;
|
||||
String errorMessageExpected = "Resume Delinquency Action can only be created during an active pause";
|
||||
errorMessageAssertation(response, errorCodeExpected, errorMessageExpected);
|
||||
}
|
||||
|
||||
@Then("Initiating a DELINQUENCY RESUME with start date other than actual business date results an error - startDate: {string}")
|
||||
public void delinquencyResumeStartDateError(String startDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostLoansDelinquencyActionRequest request = new PostLoansDelinquencyActionRequest()//
|
||||
.action("resume")//
|
||||
.startDate(startDate)//
|
||||
.dateFormat(DATE_FORMAT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostLoansDelinquencyActionResponse> response = loansApi.createLoanDelinquencyAction(loanId, request).execute();
|
||||
int errorCodeExpected = 400;
|
||||
String errorMessageExpected = "Start date of the Resume Delinquency action must be the current business date";
|
||||
errorMessageAssertation(response, errorCodeExpected, errorMessageExpected);
|
||||
}
|
||||
|
||||
@Then("Initiating a DELINQUENCY RESUME with an endDate results an error - startDate: {string}, endDate: {string}")
|
||||
public void delinquencyResumeWithEndDateError(String startDate, String endDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostLoansDelinquencyActionRequest request = new PostLoansDelinquencyActionRequest()//
|
||||
.action("resume")//
|
||||
.startDate(startDate)//
|
||||
.endDate(endDate)//
|
||||
.dateFormat(DATE_FORMAT)//
|
||||
.locale(DEFAULT_LOCALE);//
|
||||
|
||||
Response<PostLoansDelinquencyActionResponse> response = loansApi.createLoanDelinquencyAction(loanId, request).execute();
|
||||
int errorCodeExpected = 400;
|
||||
String errorMessageExpected = "Resume Delinquency action can not have end date";
|
||||
errorMessageAssertation(response, errorCodeExpected, errorMessageExpected);
|
||||
}
|
||||
|
||||
@Then("Installment level delinquency event has correct data")
|
||||
public void installmentLevelDelinquencyEventCheck() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
eventCheckHelper.installmentLevelDelinquencyRangeChangeEventCheck(loanId);
|
||||
}
|
||||
|
||||
@Then("INSTALLMENT level delinquency is null")
|
||||
public void installmentLevelDelinquencyNull() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetails);
|
||||
List<GetLoansLoanIdLoanInstallmentLevelDelinquency> installmentLevelDelinquency = loanDetails.body().getDelinquent()
|
||||
.getInstallmentLevelDelinquency() == null ? null : loanDetails.body().getDelinquent().getInstallmentLevelDelinquency();
|
||||
assertThat(installmentLevelDelinquency).isNull();
|
||||
}
|
||||
|
||||
@Then("Loan has the following LOAN level delinquency data:")
|
||||
public void loanDelinquencyDataCheck(DataTable table) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
List<String> expectedValuesList = table.asLists().get(1);
|
||||
DelinquencyRange expectedDelinquencyRange = DelinquencyRange.valueOf(expectedValuesList.get(0));
|
||||
String expectedDelinquencyRangeValue = expectedDelinquencyRange.getValue();
|
||||
expectedValuesList.set(0, expectedDelinquencyRangeValue);
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetails);
|
||||
String actualDelinquencyRangeValue = loanDetails.body().getDelinquencyRange() == null ? "NO_DELINQUENCY"
|
||||
: loanDetails.body().getDelinquencyRange().getClassification();
|
||||
GetLoansLoanIdDelinquencySummary delinquent = loanDetails.body().getDelinquent();
|
||||
List<String> actualValuesList = List.of(actualDelinquencyRangeValue, delinquent.getDelinquentAmount().toString(),
|
||||
delinquent.getDelinquentDate() == null ? "null" : FORMATTER.format(delinquent.getDelinquentDate()),
|
||||
delinquent.getDelinquentDays().toString(), delinquent.getPastDueDays().toString());
|
||||
|
||||
assertThat(actualValuesList).as(ErrorMessageHelper.wrongValueInLoanLevelDelinquencyData(actualValuesList, expectedValuesList))
|
||||
.isEqualTo(expectedValuesList);
|
||||
}
|
||||
|
||||
@Then("Loan has the following INSTALLMENT level delinquency data:")
|
||||
public void loanDelinquencyInstallmentLevelDataCheck(DataTable table) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetails);
|
||||
List<GetLoansLoanIdLoanInstallmentLevelDelinquency> installmentLevelDelinquency = loanDetails.body().getDelinquent()
|
||||
.getInstallmentLevelDelinquency();
|
||||
|
||||
List<List<String>> data = table.asLists();
|
||||
assertThat(installmentLevelDelinquency.size())
|
||||
.as(ErrorMessageHelper.nrOfLinesWrongInInstallmentLevelDelinquencyData(installmentLevelDelinquency.size(), data.size() - 1))
|
||||
.isEqualTo(data.size() - 1);
|
||||
for (int i = 1; i < data.size(); i++) {
|
||||
DelinquencyRange expectedDelinquencyRange = DelinquencyRange.valueOf(data.get(i).get(1));
|
||||
String expectedDelinquencyRangeValue = expectedDelinquencyRange.getValue();
|
||||
|
||||
List<String> expectedValuesList = data.get(i);
|
||||
expectedValuesList.set(1, expectedDelinquencyRangeValue);
|
||||
|
||||
List<String> actualValuesList = List.of(String.valueOf(installmentLevelDelinquency.get(i - 1).getRangeId()),
|
||||
installmentLevelDelinquency.get(i - 1).getClassification(),
|
||||
installmentLevelDelinquency.get(i - 1).getDelinquentAmount().setScale(2, RoundingMode.HALF_DOWN).toString());
|
||||
assertThat(actualValuesList)
|
||||
.as(ErrorMessageHelper.wrongValueInLineInInstallmentLevelDelinquencyData(i, actualValuesList, expectedValuesList))
|
||||
.isEqualTo(expectedValuesList);
|
||||
}
|
||||
}
|
||||
|
||||
@Then("Loan Delinquency pause periods has the following data:")
|
||||
public void loanDelinquencyPauseDataCheck(DataTable table) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
List<List<String>> expectedData = table.asLists();
|
||||
Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetails);
|
||||
|
||||
List<GetLoansLoanIdDelinquencyPausePeriod> delinquencyPausePeriods = loanDetails.body().getDelinquent()
|
||||
.getDelinquencyPausePeriods();
|
||||
|
||||
assertThat(delinquencyPausePeriods.size())
|
||||
.as(ErrorMessageHelper.nrOfLinesWrongInLoanDelinquencyPauseData(delinquencyPausePeriods.size(), expectedData.size() - 1))
|
||||
.isEqualTo(expectedData.size() - 1);
|
||||
|
||||
for (int i = 1; i < expectedData.size(); i++) {
|
||||
List<String> expectedValuesList = expectedData.get(i);
|
||||
|
||||
List<List<String>> actualValuesList = delinquencyPausePeriods.stream()
|
||||
.map(t -> fetchValuesOfDelinquencyPausePeriods(table.row(0), t)).collect(Collectors.toList());
|
||||
|
||||
boolean containsExpectedValues = actualValuesList.stream().anyMatch(actualValues -> actualValues.equals(expectedValuesList));
|
||||
assertThat(containsExpectedValues)
|
||||
.as(ErrorMessageHelper.wrongValueInLineInDelinquencyPausePeriodData(i, actualValuesList, expectedValuesList)).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Then("Loan details delinquent.nextPaymentDueDate will be {string}")
|
||||
public void nextPaymentDueDateCheck(String expectedDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetails);
|
||||
String actualDate = FORMATTER.format(loanDetails.body().getDelinquent().getNextPaymentDueDate());
|
||||
|
||||
assertThat(actualDate).as(ErrorMessageHelper.wrongDataInNextPaymentDueDate(actualDate, expectedDate)).isEqualTo(expectedDate);
|
||||
}
|
||||
|
||||
@Then("LoanAccountDelinquencyRangeDataV1 has delinquencyRange field with value {string}")
|
||||
public void checkDelinquencyRangeInEvent(String expectedRange) {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
DelinquencyRange expectedDelinquencyRange = DelinquencyRange.valueOf(expectedRange);
|
||||
String expectedDelinquencyRangeValue = expectedDelinquencyRange.getValue();
|
||||
|
||||
eventAssertion.assertEvent(LoanDelinquencyRangeChangeEvent.class, loanId)//
|
||||
.extractingData(loanAccountDelinquencyRangeDataV1 -> { //
|
||||
String actualDelinquencyRangeValue = loanAccountDelinquencyRangeDataV1.getDelinquencyRange().getClassification();//
|
||||
assertThat(actualDelinquencyRangeValue)//
|
||||
.as(ErrorMessageHelper.delinquencyRangeError(actualDelinquencyRangeValue, expectedDelinquencyRangeValue))//
|
||||
.isEqualTo(expectedDelinquencyRangeValue);//
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Then("LoanDelinquencyRangeChangeBusinessEvent has the same Delinquency range, date and amount as in LoanDetails on both loan- and installment-level")
|
||||
public void checkDelinquencyRangeInEvent() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "", "", "").execute();
|
||||
GetDelinquencyRangesResponse delinquencyRange = loanDetails.body().getDelinquencyRange();
|
||||
GetLoansLoanIdDelinquencySummary delinquent = loanDetails.body().getDelinquent();
|
||||
|
||||
eventAssertion.assertEvent(LoanDelinquencyRangeChangeEvent.class, loanId)//
|
||||
.extractingData(loanAccountDelinquencyRangeDataV1 -> { //
|
||||
Long loanLevelDelinquencyRangeId = loanAccountDelinquencyRangeDataV1.getDelinquencyRange().getId();
|
||||
String loanLevelDelinquencyRange = loanAccountDelinquencyRangeDataV1.getDelinquencyRange().getClassification();
|
||||
String loanLevelDelinquentDate = loanAccountDelinquencyRangeDataV1.getDelinquentDate();
|
||||
BigDecimal loanLevelTotalAmount = loanAccountDelinquencyRangeDataV1.getAmount().getTotalAmount();
|
||||
|
||||
Long loanLevelDelinquencyRangeIdExpected = delinquencyRange.getId();
|
||||
String loanLevelDelinquencyRangeExpected = delinquencyRange.getClassification();
|
||||
String loanLevelDelinquentDateExpected = FORMATTER.format(delinquent.getDelinquentDate());
|
||||
BigDecimal loanLevelTotalAmountExpected = new BigDecimal(delinquent.getDelinquentAmount());
|
||||
|
||||
assertThat(loanLevelDelinquencyRangeId)//
|
||||
.as(ErrorMessageHelper.wrongValueInLoanDelinquencyRangeChangeBusinessEvent4(loanLevelDelinquencyRangeId,
|
||||
loanLevelDelinquencyRangeIdExpected))//
|
||||
.isEqualTo(loanLevelDelinquencyRangeIdExpected);//
|
||||
assertThat(loanLevelDelinquencyRange)//
|
||||
.as(ErrorMessageHelper.wrongValueInLoanDelinquencyRangeChangeBusinessEvent5(loanLevelDelinquencyRange,
|
||||
loanLevelDelinquencyRangeExpected))//
|
||||
.isEqualTo(loanLevelDelinquencyRangeExpected);//
|
||||
assertThat(loanLevelDelinquentDate)//
|
||||
.as(ErrorMessageHelper.wrongValueInLoanDelinquencyRangeChangeBusinessEvent7(loanLevelDelinquentDate,
|
||||
loanLevelDelinquentDateExpected))//
|
||||
.isEqualTo(loanLevelDelinquentDateExpected);//
|
||||
assertThat(loanLevelTotalAmount)//
|
||||
.as(ErrorMessageHelper.wrongValueInLoanDelinquencyRangeChangeBusinessEvent6(loanLevelTotalAmount,
|
||||
loanLevelTotalAmountExpected))//
|
||||
.isEqualTo(loanLevelTotalAmountExpected);//
|
||||
|
||||
List<GetLoansLoanIdLoanInstallmentLevelDelinquency> installmentLevelDelinquencyBucketsExpected = delinquent
|
||||
.getInstallmentLevelDelinquency();
|
||||
List<LoanInstallmentDelinquencyBucketDataV1> installmentDelinquencyBuckets = loanAccountDelinquencyRangeDataV1
|
||||
.getInstallmentDelinquencyBuckets();
|
||||
for (int i = 0; i < installmentDelinquencyBuckets.size(); i++) {
|
||||
Long installmentLevelDelinquencyRangeId = installmentDelinquencyBuckets.get(i).getDelinquencyRange().getId();
|
||||
String installmentLevelDelinquencyRange = installmentDelinquencyBuckets.get(i).getDelinquencyRange()
|
||||
.getClassification();
|
||||
BigDecimal installmentLevelTotalAmount = installmentDelinquencyBuckets.get(i).getAmount().getTotalAmount();
|
||||
|
||||
Long installmentLevelDelinquencyRangeIdExpected = installmentLevelDelinquencyBucketsExpected.get(i).getRangeId();
|
||||
String installmentLevelDelinquencyRangeExpected = installmentLevelDelinquencyBucketsExpected.get(i)
|
||||
.getClassification();
|
||||
BigDecimal installmentLevelTotalAmountExpected = installmentLevelDelinquencyBucketsExpected.get(i)
|
||||
.getDelinquentAmount();
|
||||
|
||||
assertThat(installmentLevelDelinquencyRangeId)//
|
||||
.as(ErrorMessageHelper.wrongValueInLoanDelinquencyRangeChangeBusinessEvent1(
|
||||
installmentLevelDelinquencyRangeId, installmentLevelDelinquencyRangeIdExpected))//
|
||||
.isEqualTo(installmentLevelDelinquencyRangeIdExpected);//
|
||||
assertThat(installmentLevelDelinquencyRange)//
|
||||
.as(ErrorMessageHelper.wrongValueInLoanDelinquencyRangeChangeBusinessEvent2(
|
||||
installmentLevelDelinquencyRange, installmentLevelDelinquencyRangeExpected))//
|
||||
.isEqualTo(installmentLevelDelinquencyRangeExpected);//
|
||||
assertThat(installmentLevelTotalAmount)//
|
||||
.as(ErrorMessageHelper.wrongValueInLoanDelinquencyRangeChangeBusinessEvent3(installmentLevelTotalAmount,
|
||||
installmentLevelTotalAmountExpected))//
|
||||
.isEqualTo(installmentLevelTotalAmountExpected);//
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Then("In Loan details delinquent.lastRepaymentAmount is {int} EUR with lastRepaymentDate {string}")
|
||||
public void delinquentLastRepaymentAmountCheck(int expectedLastRepaymentAmount, String expectedLastRepaymentDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetails);
|
||||
|
||||
Double expectedLastRepaymentAmount1 = Double.valueOf(expectedLastRepaymentAmount);
|
||||
Double actualLastRepaymentAmount = loanDetails.body().getDelinquent().getLastRepaymentAmount();
|
||||
String actualLastRepaymentDate = FORMATTER.format(loanDetails.body().getDelinquent().getLastRepaymentDate());
|
||||
|
||||
assertThat(actualLastRepaymentAmount)//
|
||||
.as(ErrorMessageHelper.wrongDataInDelinquentLastRepaymentAmount(actualLastRepaymentAmount, expectedLastRepaymentAmount1))//
|
||||
.isEqualTo(expectedLastRepaymentAmount);//
|
||||
assertThat(actualLastRepaymentDate)//
|
||||
.as(ErrorMessageHelper.wrongDataInDelinquentLastRepaymentDate(actualLastRepaymentDate, expectedLastRepaymentDate))//
|
||||
.isEqualTo(expectedLastRepaymentDate);//
|
||||
|
||||
log.info("loanDetails.delinquent.lastRepaymentAmount: {}", actualLastRepaymentAmount);
|
||||
log.info("loanDetails.delinquent.lastRepaymentDate: {}", actualLastRepaymentDate);
|
||||
}
|
||||
|
||||
@SuppressFBWarnings("SF_SWITCH_NO_DEFAULT")
|
||||
private List<String> fetchValuesOfDelinquencyPausePeriods(List<String> header, GetLoansLoanIdDelinquencyPausePeriod t) {
|
||||
List<String> actualValues = new ArrayList<>();
|
||||
for (String headerName : header) {
|
||||
switch (headerName) {
|
||||
case "active" -> actualValues.add(t.getActive() == null ? null : t.getActive().toString());
|
||||
case "pausePeriodStart" ->
|
||||
actualValues.add(t.getPausePeriodStart() == null ? null : FORMATTER.format(t.getPausePeriodStart()));
|
||||
case "pausePeriodEnd" -> actualValues.add(t.getPausePeriodEnd() == null ? null : FORMATTER.format(t.getPausePeriodEnd()));
|
||||
}
|
||||
}
|
||||
return actualValues;
|
||||
}
|
||||
|
||||
private void errorMessageAssertation(Response<PostLoansDelinquencyActionResponse> response, int errorCodeExpected,
|
||||
String errorMessageExpected) throws IOException {
|
||||
String errorToString = response.errorBody().string();
|
||||
ErrorResponse errorResponse = GSON.fromJson(errorToString, ErrorResponse.class);
|
||||
String errorMessageActual = errorResponse.getErrors().get(0).getDeveloperMessage();
|
||||
int errorCodeActual = response.code();
|
||||
|
||||
assertThat(errorCodeActual).as(ErrorMessageHelper.wrongErrorCode(errorCodeActual, errorCodeExpected)).isEqualTo(errorCodeExpected);
|
||||
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
|
||||
.isEqualTo(errorMessageExpected);
|
||||
|
||||
log.info("ERROR CODE: {}", errorCodeActual);
|
||||
log.info("ERROR MESSAGE: {}", errorMessageActual);
|
||||
}
|
||||
|
||||
@Then("LoanDelinquencyRangeChangeBusinessEvent is created")
|
||||
public void checkLoanDelinquencyRangeChangeBusinessEventCreated() {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
eventAssertion.assertEventRaised(LoanDelinquencyRangeChangeEvent.class, loanId);
|
||||
}
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.loan;
|
||||
|
||||
import io.cucumber.datatable.DataTable;
|
||||
import io.cucumber.java.en.Then;
|
||||
import io.cucumber.java.en.When;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.services.LoanTransactionsApi;
|
||||
import org.apache.fineract.test.factory.LoanRequestFactory;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.messaging.EventAssertion;
|
||||
import org.apache.fineract.test.messaging.event.loan.LoanReAgeEvent;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.apache.fineract.test.support.TestContextKey;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import retrofit2.Response;
|
||||
|
||||
@Slf4j
|
||||
public class LoanReAgingStepDef extends AbstractStepDef {
|
||||
|
||||
@Autowired
|
||||
private LoanTransactionsApi loanTransactionsApi;
|
||||
|
||||
@Autowired
|
||||
private EventAssertion eventAssertion;
|
||||
|
||||
@When("Admin creates a Loan re-aging transaction with the following data:")
|
||||
public void createReAgingTransaction(DataTable table) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
List<String> data = table.asLists().get(1);
|
||||
int frequencyNumber = Integer.parseInt(data.get(0));
|
||||
String frequencyType = data.get(1);
|
||||
String startDate = data.get(2);
|
||||
int numberOfInstallments = Integer.parseInt(data.get(3));
|
||||
|
||||
PostLoansLoanIdTransactionsRequest reAgingRequest = LoanRequestFactory.defaultReAgingRequest().frequencyNumber(frequencyNumber)
|
||||
.frequencyType(frequencyType).startDate(startDate).numberOfInstallments(numberOfInstallments);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> response = loanTransactionsApi.executeLoanTransaction(loanId, reAgingRequest, "reAge")
|
||||
.execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
testContext().set(TestContextKey.LOAN_REAGING_RESPONSE, response);
|
||||
}
|
||||
|
||||
@When("Admin creates a Loan re-aging transaction by Loan external ID with the following data:")
|
||||
public void createReAgingTransactionByLoanExternalId(DataTable table) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
String loanExternalId = loanResponse.body().getResourceExternalId();
|
||||
|
||||
List<String> data = table.asLists().get(1);
|
||||
int frequencyNumber = Integer.parseInt(data.get(0));
|
||||
String frequencyType = data.get(1);
|
||||
String startDate = data.get(2);
|
||||
int numberOfInstallments = Integer.parseInt(data.get(3));
|
||||
|
||||
PostLoansLoanIdTransactionsRequest reAgingRequest = LoanRequestFactory.defaultReAgingRequest().frequencyNumber(frequencyNumber)
|
||||
.frequencyType(frequencyType).startDate(startDate).numberOfInstallments(numberOfInstallments);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> response = loanTransactionsApi
|
||||
.executeLoanTransaction1(loanExternalId, reAgingRequest, "reAge").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
testContext().set(TestContextKey.LOAN_REAGING_RESPONSE, response);
|
||||
}
|
||||
|
||||
@When("Admin successfully undo Loan re-aging transaction")
|
||||
public void undoReAgingTransaction() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> response = loanTransactionsApi
|
||||
.executeLoanTransaction(loanId, new PostLoansLoanIdTransactionsRequest(), "undoReAge").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
testContext().set(TestContextKey.LOAN_REAGING_UNDO_RESPONSE, response);
|
||||
}
|
||||
|
||||
@Then("LoanReAgeBusinessEvent is created")
|
||||
public void checkLoanReAmortizeBusinessEventCreated() {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
eventAssertion.assertEventRaised(LoanReAgeEvent.class, loanId);
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.loan;
|
||||
|
||||
import io.cucumber.java.en.Then;
|
||||
import io.cucumber.java.en.When;
|
||||
import java.io.IOException;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.services.LoanTransactionsApi;
|
||||
import org.apache.fineract.test.factory.LoanRequestFactory;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.messaging.EventAssertion;
|
||||
import org.apache.fineract.test.messaging.event.loan.LoanReAmortizeEvent;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.apache.fineract.test.support.TestContextKey;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class LoanReAmortizationStepDef extends AbstractStepDef {
|
||||
|
||||
@Autowired
|
||||
private LoanTransactionsApi loanTransactionsApi;
|
||||
|
||||
@Autowired
|
||||
private EventAssertion eventAssertion;
|
||||
|
||||
@When("When Admin creates a Loan re-amortization transaction on current business date")
|
||||
public void createLoanReAmortization() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostLoansLoanIdTransactionsRequest reAmortizationRequest = LoanRequestFactory.defaultLoanReAmortizationRequest();
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> response = loanTransactionsApi
|
||||
.executeLoanTransaction(loanId, reAmortizationRequest, "reAmortize").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
testContext().set(TestContextKey.LOAN_REAMORTIZATION_RESPONSE, response);
|
||||
}
|
||||
|
||||
@When("When Admin creates a Loan re-amortization transaction on current business date by loan external ID")
|
||||
public void createLoanReAmortizationByLoanExternalId() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
String loanExternalId = loanResponse.body().getResourceExternalId();
|
||||
|
||||
PostLoansLoanIdTransactionsRequest reAmortizationRequest = LoanRequestFactory.defaultLoanReAmortizationRequest();
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> response = loanTransactionsApi
|
||||
.executeLoanTransaction1(loanExternalId, reAmortizationRequest, "reAmortize").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
testContext().set(TestContextKey.LOAN_REAMORTIZATION_RESPONSE, response);
|
||||
}
|
||||
|
||||
@When("When Admin undo Loan re-amortization transaction on current business date")
|
||||
public void undoLoanReAmortization() throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> response = loanTransactionsApi
|
||||
.executeLoanTransaction(loanId, new PostLoansLoanIdTransactionsRequest(), "undoReAmortize").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
testContext().set(TestContextKey.LOAN_REAMORTIZATION_UNDO_RESPONSE, response);
|
||||
}
|
||||
|
||||
@Then("LoanReAmortizeBusinessEvent is created")
|
||||
public void checkLoanReAmortizeBusinessEventCreated() {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
eventAssertion.assertEventRaised(LoanReAmortizeEvent.class, loanId);
|
||||
}
|
||||
}
|
||||
+564
@@ -0,0 +1,564 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.loan;
|
||||
|
||||
import static org.apache.fineract.test.data.paymenttype.DefaultPaymentType.AUTOPAY;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
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.math.RoundingMode;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.fineract.avro.loan.v1.LoanTransactionAdjustmentDataV1;
|
||||
import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdTransactions;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdTransactionsTransactionIdResponse;
|
||||
import org.apache.fineract.client.models.GetUsersUserIdResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.models.PostUsersResponse;
|
||||
import org.apache.fineract.client.services.LoanTransactionsApi;
|
||||
import org.apache.fineract.client.services.LoansApi;
|
||||
import org.apache.fineract.client.services.UsersApi;
|
||||
import org.apache.fineract.test.api.ApiProperties;
|
||||
import org.apache.fineract.test.data.TransactionType;
|
||||
import org.apache.fineract.test.data.paymenttype.DefaultPaymentType;
|
||||
import org.apache.fineract.test.data.paymenttype.PaymentTypeResolver;
|
||||
import org.apache.fineract.test.factory.LoanRequestFactory;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.helper.ErrorMessageHelper;
|
||||
import org.apache.fineract.test.helper.ErrorResponse;
|
||||
import org.apache.fineract.test.messaging.EventAssertion;
|
||||
import org.apache.fineract.test.messaging.event.EventCheckHelper;
|
||||
import org.apache.fineract.test.messaging.event.loan.LoanBalanceChangedEvent;
|
||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanAdjustTransactionBusinessEvent;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.apache.fineract.test.support.TestContextKey;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class LoanRepaymentStepDef extends AbstractStepDef {
|
||||
|
||||
public static final String DATE_FORMAT = "dd MMMM yyyy";
|
||||
public static final String DEFAULT_LOCALE = "en";
|
||||
public static final String DEFAULT_ACCOUNT_NB = "1234567890";
|
||||
public static final String DEFAULT_CHECK_NB = "1234567890";
|
||||
public static final String DEFAULT_RECEIPT_NB = "1234567890";
|
||||
public static final String DEFAULT_BANK_NB = "1234567890";
|
||||
@Autowired
|
||||
private LoanTransactionsApi loanTransactionsApi;
|
||||
|
||||
@Autowired
|
||||
private LoansApi loansApi;
|
||||
|
||||
@Autowired
|
||||
private EventAssertion eventAssertion;
|
||||
|
||||
@Autowired
|
||||
private ApiProperties apiProperties;
|
||||
|
||||
@Autowired
|
||||
private UsersApi usersApi;
|
||||
|
||||
@Autowired
|
||||
private PaymentTypeResolver paymentTypeResolver;
|
||||
|
||||
@Autowired
|
||||
private EventCheckHelper eventCheckHelper;
|
||||
|
||||
@And("Customer makes {string} repayment on {string} with {double} EUR transaction amount")
|
||||
public void makeLoanRepayment(String repaymentType, String transactionDate, double transactionAmount) throws IOException {
|
||||
makeRepayment(repaymentType, transactionDate, transactionAmount, null);
|
||||
}
|
||||
|
||||
@And("Customer makes {string} repayment on {string} with {double} EUR transaction amount and check external owner")
|
||||
public void makeLoanRepaymentAndCheckOwner(String repaymentType, String transactionDate, double transactionAmount) throws IOException {
|
||||
String transferExternalOwnerId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_OWNER_EXTERNAL_ID);
|
||||
makeRepayment(repaymentType, transactionDate, transactionAmount, transferExternalOwnerId);
|
||||
}
|
||||
|
||||
private void makeRepayment(String repaymentType, String transactionDate, double transactionAmount, String transferExternalOwnerId)
|
||||
throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
DefaultPaymentType paymentType = DefaultPaymentType.valueOf(repaymentType);
|
||||
long paymentTypeValue = paymentTypeResolver.resolve(paymentType);
|
||||
|
||||
PostLoansLoanIdTransactionsRequest repaymentRequest = LoanRequestFactory.defaultRepaymentRequest().transactionDate(transactionDate)
|
||||
.transactionAmount(transactionAmount).paymentTypeId(paymentTypeValue).dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE);
|
||||
|
||||
Map<String, String> headerMap = new HashMap<>();
|
||||
String idempotencyKey = UUID.randomUUID().toString();
|
||||
testContext().set(TestContextKey.TRANSACTION_IDEMPOTENCY_KEY, idempotencyKey);
|
||||
headerMap.put("Idempotency-Key", idempotencyKey);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> repaymentResponse = loanTransactionsApi
|
||||
.executeLoanTransaction(loanId, repaymentRequest, "repayment", headerMap).execute();
|
||||
testContext().set(TestContextKey.LOAN_REPAYMENT_RESPONSE, repaymentResponse);
|
||||
ErrorHelper.checkSuccessfulApiCall(repaymentResponse);
|
||||
EventAssertion.EventAssertionBuilder<LoanTransactionDataV1> transactionEvent = eventCheckHelper
|
||||
.transactionEventCheck(repaymentResponse, TransactionType.REPAYMENT, transferExternalOwnerId);
|
||||
testContext().set(TestContextKey.TRANSACTION_EVENT, transactionEvent);
|
||||
eventAssertion.assertEventRaised(LoanBalanceChangedEvent.class, loanId);
|
||||
}
|
||||
|
||||
@And("Created user makes {string} repayment on {string} with {double} EUR transaction amount")
|
||||
public void makeRepaymentWithGivenUser(String repaymentType, String transactionDate, double transactionAmount) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
DefaultPaymentType paymentType = DefaultPaymentType.valueOf(repaymentType);
|
||||
Long paymentTypeValue = paymentTypeResolver.resolve(paymentType);
|
||||
|
||||
PostLoansLoanIdTransactionsRequest repaymentRequest = LoanRequestFactory.defaultRepaymentRequest().transactionDate(transactionDate)
|
||||
.transactionAmount(transactionAmount).paymentTypeId(paymentTypeValue).dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE);
|
||||
|
||||
Map<String, String> headerMap = new HashMap<>();
|
||||
String idempotencyKey = UUID.randomUUID().toString();
|
||||
testContext().set(TestContextKey.TRANSACTION_IDEMPOTENCY_KEY, idempotencyKey);
|
||||
headerMap.put("Idempotency-Key", idempotencyKey);
|
||||
|
||||
Response<PostUsersResponse> createUserResponse = testContext().get(TestContextKey.CREATED_SIMPLE_USER_RESPONSE);
|
||||
Long createdUserId = createUserResponse.body().getResourceId();
|
||||
Response<GetUsersUserIdResponse> user = usersApi.retrieveOne31(createdUserId).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(user);
|
||||
String authorizationString = user.body().getUsername() + ":" + apiProperties.getPassword();
|
||||
Base64 base64 = new Base64();
|
||||
headerMap.put("Authorization",
|
||||
"Basic " + new String(base64.encode(authorizationString.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> repaymentResponse = loanTransactionsApi
|
||||
.executeLoanTransaction(loanId, repaymentRequest, "repayment", headerMap).execute();
|
||||
testContext().set(TestContextKey.LOAN_REPAYMENT_RESPONSE, repaymentResponse);
|
||||
ErrorHelper.checkSuccessfulApiCall(repaymentResponse);
|
||||
eventAssertion.assertEventRaised(LoanBalanceChangedEvent.class, loanId);
|
||||
}
|
||||
|
||||
@And("Customer makes externalID controlled {string} repayment on {string} with {double} EUR transaction amount")
|
||||
public void makeRepaymentByExternalId(String repaymentType, String transactionDate, double transactionAmount) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
String resourceExternalId = loanResponse.body().getResourceExternalId();
|
||||
|
||||
DefaultPaymentType paymentType = DefaultPaymentType.valueOf(repaymentType);
|
||||
Long paymentTypeValue = paymentTypeResolver.resolve(paymentType);
|
||||
|
||||
PostLoansLoanIdTransactionsRequest repaymentRequest = LoanRequestFactory.defaultRepaymentRequest().transactionDate(transactionDate)
|
||||
.transactionAmount(transactionAmount).paymentTypeId(paymentTypeValue).dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE);
|
||||
|
||||
Map<String, String> headerMap = new HashMap<>();
|
||||
String idempotencyKey = UUID.randomUUID().toString();
|
||||
testContext().set(TestContextKey.TRANSACTION_IDEMPOTENCY_KEY, idempotencyKey);
|
||||
headerMap.put("Idempotency-Key", idempotencyKey);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> repaymentResponse = loanTransactionsApi
|
||||
.executeLoanTransaction1(resourceExternalId, repaymentRequest, "repayment", headerMap).execute();
|
||||
|
||||
testContext().set(TestContextKey.LOAN_REPAYMENT_RESPONSE, repaymentResponse);
|
||||
ErrorHelper.checkSuccessfulApiCall(repaymentResponse);
|
||||
eventAssertion.assertEventRaised(LoanBalanceChangedEvent.class, loanId);
|
||||
}
|
||||
|
||||
@And("Created user makes externalID controlled {string} repayment on {string} with {double} EUR transaction amount")
|
||||
public void makeRepaymentWithGivenUserByExternalId(String repaymentType, String transactionDate, double transactionAmount)
|
||||
throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
String resourceExternalId = loanResponse.body().getResourceExternalId();
|
||||
|
||||
DefaultPaymentType paymentType = DefaultPaymentType.valueOf(repaymentType);
|
||||
Long paymentTypeValue = paymentTypeResolver.resolve(paymentType);
|
||||
|
||||
PostLoansLoanIdTransactionsRequest repaymentRequest = LoanRequestFactory.defaultRepaymentRequest().transactionDate(transactionDate)
|
||||
.transactionAmount(transactionAmount).paymentTypeId(paymentTypeValue).dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE);
|
||||
|
||||
Map<String, String> headerMap = new HashMap<>();
|
||||
String idempotencyKey = UUID.randomUUID().toString();
|
||||
testContext().set(TestContextKey.TRANSACTION_IDEMPOTENCY_KEY, idempotencyKey);
|
||||
headerMap.put("Idempotency-Key", idempotencyKey);
|
||||
|
||||
Response<PostUsersResponse> createUserResponse = testContext().get(TestContextKey.CREATED_SIMPLE_USER_RESPONSE);
|
||||
Long createdUserId = createUserResponse.body().getResourceId();
|
||||
Response<GetUsersUserIdResponse> user = usersApi.retrieveOne31(createdUserId).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(user);
|
||||
String authorizationString = user.body().getUsername() + ":" + apiProperties.getPassword();
|
||||
Base64 base64 = new Base64();
|
||||
headerMap.put("Authorization",
|
||||
"Basic " + new String(base64.encode(authorizationString.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> repaymentResponse = loanTransactionsApi
|
||||
.executeLoanTransaction1(resourceExternalId, repaymentRequest, "repayment", headerMap).execute();
|
||||
testContext().set(TestContextKey.LOAN_REPAYMENT_RESPONSE, repaymentResponse);
|
||||
ErrorHelper.checkSuccessfulApiCall(repaymentResponse);
|
||||
eventAssertion.assertEventRaised(LoanBalanceChangedEvent.class, loanId);
|
||||
}
|
||||
|
||||
@And("Customer not able to make {string} repayment on {string} with {double} EUR transaction amount")
|
||||
public void makeLoanRepaymentFails(String repaymentType, String transactionDate, double transactionAmount) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
DefaultPaymentType paymentType = DefaultPaymentType.valueOf(repaymentType);
|
||||
Long paymentTypeValue = paymentTypeResolver.resolve(paymentType);
|
||||
|
||||
PostLoansLoanIdTransactionsRequest repaymentRequest = LoanRequestFactory.defaultRepaymentRequest().transactionDate(transactionDate)
|
||||
.transactionAmount(transactionAmount).paymentTypeId(paymentTypeValue).dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> repaymentResponse = loanTransactionsApi
|
||||
.executeLoanTransaction(loanId, repaymentRequest, "repayment").execute();
|
||||
ErrorResponse errorDetails = ErrorResponse.from(repaymentResponse);
|
||||
assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(400);
|
||||
assertThat(errorDetails.getSingleError().getDeveloperMessage()).isEqualTo(ErrorMessageHelper.loanRepaymentOnClosedLoanFailureMsg());
|
||||
}
|
||||
|
||||
@Then("Customer not able to make a repayment undo on {string} due to charge off")
|
||||
public void makeLoanRepaymentUndoAfterChargeOff(String transactionDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
Response<PostLoansLoanIdTransactionsResponse> transactionResponse = testContext().get(TestContextKey.LOAN_REPAYMENT_RESPONSE);
|
||||
Long loanId = loanResponse.body().getLoanId();
|
||||
Long transactionId = transactionResponse.body().getResourceId();
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> repaymentResponse = testContext().get(TestContextKey.LOAN_REPAYMENT_RESPONSE);
|
||||
|
||||
PostLoansLoanIdTransactionsTransactionIdRequest repaymentUndoRequest = LoanRequestFactory.defaultRepaymentUndoRequest()
|
||||
.transactionDate(transactionDate).dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> repaymentUndoResponse = loanTransactionsApi
|
||||
.adjustLoanTransaction(loanId, repaymentResponse.body().getResourceId(), repaymentUndoRequest, "").execute();
|
||||
ErrorResponse errorDetails = ErrorResponse.from(repaymentUndoResponse);
|
||||
assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.repaymentUndoFailureDueToChargeOffCodeMsg()).isEqualTo(403);
|
||||
assertThat(errorDetails.getSingleError().getDeveloperMessage())
|
||||
.isEqualTo(ErrorMessageHelper.repaymentUndoFailureDueToChargeOff(transactionId));
|
||||
}
|
||||
|
||||
@And("Customer makes {string} repayment on {string} with {double} EUR transaction amount \\(and transaction fails because of wrong date)")
|
||||
public void makeLoanRepaymentWithWrongDate(String repaymentType, String transactionDate, double transactionAmount) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
DefaultPaymentType paymentType = DefaultPaymentType.valueOf(repaymentType);
|
||||
Long paymentTypeValue = paymentTypeResolver.resolve(paymentType);
|
||||
|
||||
PostLoansLoanIdTransactionsRequest repaymentRequest = LoanRequestFactory.defaultRepaymentRequest().transactionDate(transactionDate)
|
||||
.transactionAmount(transactionAmount).paymentTypeId(paymentTypeValue).dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> repaymentResponse = loanTransactionsApi
|
||||
.executeLoanTransaction(loanId, repaymentRequest, "repayment").execute();
|
||||
testContext().set(TestContextKey.LOAN_REPAYMENT_RESPONSE, repaymentResponse);
|
||||
}
|
||||
|
||||
@When("Refund happens on {string} with {double} EUR transaction amount")
|
||||
public void makeRefund(String transactionDate, double transactionAmount) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
PostLoansLoanIdTransactionsRequest refundRequest = LoanRequestFactory.defaultRefundRequest().transactionDate(transactionDate)
|
||||
.transactionAmount(transactionAmount).paymentTypeId(paymentTypeResolver.resolve(AUTOPAY)).dateFormat(DATE_FORMAT)
|
||||
.locale(DEFAULT_LOCALE).accountNumber(DEFAULT_ACCOUNT_NB).checkNumber(DEFAULT_CHECK_NB).receiptNumber(DEFAULT_RECEIPT_NB)
|
||||
.bankNumber(DEFAULT_BANK_NB);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> refundResponse = loanTransactionsApi
|
||||
.executeLoanTransaction(loanId, refundRequest, "payoutRefund").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(refundResponse);
|
||||
testContext().set(TestContextKey.LOAN_REFUND_RESPONSE, refundResponse);
|
||||
}
|
||||
|
||||
@When("Refund undo happens on {string}")
|
||||
public void makeRefundUndo(String transactionDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
Response<PostLoansLoanIdTransactionsResponse> refundResponse = testContext().get(TestContextKey.LOAN_REFUND_RESPONSE);
|
||||
|
||||
PostLoansLoanIdTransactionsTransactionIdRequest refundUndoRequest = LoanRequestFactory.defaultRefundUndoRequest()
|
||||
.transactionDate(transactionDate).dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> refundUndoResponse = loanTransactionsApi
|
||||
.adjustLoanTransaction(loanId, refundResponse.body().getResourceId(), refundUndoRequest, "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(refundUndoResponse);
|
||||
testContext().set(TestContextKey.LOAN_REPAYMENT_UNDO_RESPONSE, refundUndoResponse);
|
||||
EventAssertion.EventAssertionBuilder<LoanTransactionAdjustmentDataV1> eventAssertionBuilder = eventAssertion
|
||||
.assertEvent(LoanAdjustTransactionBusinessEvent.class, refundResponse.body().getResourceId());
|
||||
eventAssertionBuilder
|
||||
.extractingData(loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getId())
|
||||
.isEqualTo(refundResponse.body().getResourceId());
|
||||
eventAssertionBuilder
|
||||
.extractingData(
|
||||
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getManuallyReversed())
|
||||
.isEqualTo(Boolean.TRUE);
|
||||
eventAssertionBuilder.extractingData(LoanTransactionAdjustmentDataV1::getNewTransactionDetail).isEqualTo(null);
|
||||
}
|
||||
|
||||
@When("Customer makes a repayment undo on {string}")
|
||||
public void makeLoanRepaymentUndo(String transactionDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
Response<PostLoansLoanIdTransactionsResponse> repaymentResponse = testContext().get(TestContextKey.LOAN_REPAYMENT_RESPONSE);
|
||||
|
||||
PostLoansLoanIdTransactionsTransactionIdRequest repaymentUndoRequest = LoanRequestFactory.defaultRepaymentUndoRequest()
|
||||
.transactionDate(transactionDate).dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> repaymentUndoResponse = loanTransactionsApi
|
||||
.adjustLoanTransaction(loanId, repaymentResponse.body().getResourceId(), repaymentUndoRequest, "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(repaymentUndoResponse);
|
||||
testContext().set(TestContextKey.LOAN_REPAYMENT_UNDO_RESPONSE, repaymentUndoResponse);
|
||||
EventAssertion.EventAssertionBuilder<LoanTransactionAdjustmentDataV1> eventAssertionBuilder = eventAssertion
|
||||
.assertEvent(LoanAdjustTransactionBusinessEvent.class, repaymentResponse.body().getResourceId());
|
||||
eventAssertionBuilder
|
||||
.extractingData(loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getId())
|
||||
.isEqualTo(repaymentResponse.body().getResourceId());
|
||||
eventAssertionBuilder
|
||||
.extractingData(
|
||||
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getManuallyReversed())
|
||||
.isEqualTo(Boolean.TRUE);
|
||||
eventAssertionBuilder.extractingData(LoanTransactionAdjustmentDataV1::getNewTransactionDetail).isEqualTo(null);
|
||||
}
|
||||
|
||||
@Then("Loan {string} transaction adjust amount {double} must return {int} code")
|
||||
public void makeLoanRepaymentAdjustFail(String transactionType, double transactionAmount, int codeExpected) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
Response<PostLoansLoanIdTransactionsResponse> repaymentResponse = testContext().get(transactionType);
|
||||
|
||||
PostLoansLoanIdTransactionsTransactionIdRequest repaymentUndoRequest = LoanRequestFactory.defaultRepaymentUndoRequest()
|
||||
.transactionAmount(transactionAmount);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> repaymentUndoResponse = loanTransactionsApi
|
||||
.adjustLoanTransaction(loanId, repaymentResponse.body().getResourceId(), repaymentUndoRequest, "").execute();
|
||||
assertThat(repaymentUndoResponse.code()).isEqualTo(codeExpected);
|
||||
}
|
||||
|
||||
@When("Customer undo {string}th repayment on {string}")
|
||||
public void undoNthRepayment(String nthItemStr, String transactionDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
List<GetLoansLoanIdTransactions> transactions = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute().body()
|
||||
.getTransactions();
|
||||
|
||||
int nthItem = Integer.parseInt(nthItemStr) - 1;
|
||||
GetLoansLoanIdTransactions targetTransaction = transactions.stream().filter(t -> Boolean.TRUE.equals(t.getType().getRepayment()))
|
||||
.toList().get(nthItem);
|
||||
|
||||
PostLoansLoanIdTransactionsTransactionIdRequest repaymentUndoRequest = LoanRequestFactory.defaultRepaymentUndoRequest()
|
||||
.transactionDate(transactionDate).dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> repaymentUndoResponse = loanTransactionsApi
|
||||
.adjustLoanTransaction(loanId, targetTransaction.getId(), repaymentUndoRequest, "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(repaymentUndoResponse);
|
||||
testContext().set(TestContextKey.LOAN_REPAYMENT_UNDO_RESPONSE, repaymentUndoResponse);
|
||||
EventAssertion.EventAssertionBuilder<LoanTransactionAdjustmentDataV1> eventAssertionBuilder = eventAssertion
|
||||
.assertEvent(LoanAdjustTransactionBusinessEvent.class, targetTransaction.getId());
|
||||
eventAssertionBuilder
|
||||
.extractingData(loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getId())
|
||||
.isEqualTo(targetTransaction.getId());
|
||||
eventAssertionBuilder
|
||||
.extractingData(
|
||||
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getManuallyReversed())
|
||||
.isEqualTo(Boolean.TRUE);
|
||||
eventAssertionBuilder.extractingData(LoanTransactionAdjustmentDataV1::getNewTransactionDetail).isEqualTo(null);
|
||||
}
|
||||
|
||||
@When("Customer undo {string}th transaction made on {string}")
|
||||
public void undoNthTransaction(String nthItemStr, String transactionDate) throws IOException {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
List<GetLoansLoanIdTransactions> transactions = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute().body()
|
||||
.getTransactions();
|
||||
|
||||
int nthItem = Integer.parseInt(nthItemStr) - 1;
|
||||
GetLoansLoanIdTransactions targetTransaction = transactions.stream()
|
||||
.filter(t -> transactionDate.equals(formatter.format(t.getDate()))).toList().get(nthItem);
|
||||
|
||||
PostLoansLoanIdTransactionsTransactionIdRequest transactionUndoRequest = LoanRequestFactory.defaultTransactionUndoRequest()
|
||||
.transactionDate(transactionDate);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> transactionUndoResponse = loanTransactionsApi
|
||||
.adjustLoanTransaction(loanId, targetTransaction.getId(), transactionUndoRequest, "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(transactionUndoResponse);
|
||||
testContext().set(TestContextKey.LOAN_TRANSACTION_UNDO_RESPONSE, transactionUndoResponse);
|
||||
EventAssertion.EventAssertionBuilder<LoanTransactionAdjustmentDataV1> eventAssertionBuilder = eventAssertion
|
||||
.assertEvent(LoanAdjustTransactionBusinessEvent.class, targetTransaction.getId());
|
||||
eventAssertionBuilder
|
||||
.extractingData(loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getId())
|
||||
.isEqualTo(targetTransaction.getId());
|
||||
eventAssertionBuilder
|
||||
.extractingData(
|
||||
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getManuallyReversed())
|
||||
.isEqualTo(Boolean.TRUE);
|
||||
eventAssertionBuilder.extractingData(LoanTransactionAdjustmentDataV1::getNewTransactionDetail).isEqualTo(null);
|
||||
}
|
||||
|
||||
@When("Customer undo {string}th {string} transaction made on {string}")
|
||||
public void undoNthTransactionType(String nthItemStr, String transactionType, String transactionDate) throws IOException {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
List<GetLoansLoanIdTransactions> transactions = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute().body()
|
||||
.getTransactions();
|
||||
|
||||
int nthItem = Integer.parseInt(nthItemStr) - 1;
|
||||
GetLoansLoanIdTransactions targetTransaction = transactions//
|
||||
.stream()//
|
||||
.filter(t -> transactionDate.equals(formatter.format(t.getDate())) && transactionType.equals(t.getType().getValue()))//
|
||||
.toList()//
|
||||
.get(nthItem);//
|
||||
|
||||
PostLoansLoanIdTransactionsTransactionIdRequest transactionUndoRequest = LoanRequestFactory.defaultTransactionUndoRequest()
|
||||
.transactionDate(transactionDate);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> transactionUndoResponse = loanTransactionsApi
|
||||
.adjustLoanTransaction(loanId, targetTransaction.getId(), transactionUndoRequest, "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(transactionUndoResponse);
|
||||
testContext().set(TestContextKey.LOAN_TRANSACTION_UNDO_RESPONSE, transactionUndoResponse);
|
||||
EventAssertion.EventAssertionBuilder<LoanTransactionAdjustmentDataV1> eventAssertionBuilder = eventAssertion
|
||||
.assertEvent(LoanAdjustTransactionBusinessEvent.class, targetTransaction.getId());
|
||||
eventAssertionBuilder
|
||||
.extractingData(loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getId())
|
||||
.isEqualTo(targetTransaction.getId());
|
||||
eventAssertionBuilder
|
||||
.extractingData(
|
||||
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getManuallyReversed())
|
||||
.isEqualTo(Boolean.TRUE);
|
||||
eventAssertionBuilder.extractingData(LoanTransactionAdjustmentDataV1::getNewTransactionDetail).isEqualTo(null);
|
||||
}
|
||||
|
||||
@Then("Repayment transaction is created with {double} amount and {string} type")
|
||||
public void loanRepaymentStatus(double repaymentAmount, String paymentType) throws IOException {
|
||||
Response<PostLoansLoanIdTransactionsResponse> repaymentResponse = testContext().get(TestContextKey.LOAN_REPAYMENT_RESPONSE);
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
Response<GetLoansLoanIdTransactionsTransactionIdResponse> transactionResponse = loanTransactionsApi
|
||||
.retrieveTransaction(loanId, repaymentResponse.body().getResourceId(), "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(transactionResponse);
|
||||
assertThat(transactionResponse.body().getAmount()).isEqualTo(repaymentAmount);
|
||||
assertThat(transactionResponse.body().getPaymentDetailData().getPaymentType().getName()).isEqualTo(paymentType);
|
||||
|
||||
}
|
||||
|
||||
@Then("Repayment failed because the repayment date is after the business date")
|
||||
public void repaymentDateFailure() {
|
||||
Response<PostLoansLoanIdTransactionsResponse> response = testContext().get(TestContextKey.LOAN_REPAYMENT_RESPONSE);
|
||||
|
||||
ErrorResponse errorDetails = ErrorResponse.from(response);
|
||||
|
||||
assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(403);
|
||||
assertThat(errorDetails.getSingleError().getDeveloperMessage()).isEqualTo(ErrorMessageHelper.transactionDateInFutureFailureMsg());
|
||||
}
|
||||
|
||||
@Then("Amounts are distributed equally in loan repayment schedule in case of total amount {double}")
|
||||
public void amountsEquallyDistributedInSchedule(double totalAmount) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId1 = loanResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> getLoansLoanIdResponseCall = loansApi
|
||||
.retrieveLoan(loanId1, false, "all", "guarantors,futureSchedule", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(getLoansLoanIdResponseCall);
|
||||
|
||||
List<GetLoansLoanIdRepaymentPeriod> periods = getLoansLoanIdResponseCall.body().getRepaymentSchedule().getPeriods();
|
||||
|
||||
BigDecimal expectedAmount = new BigDecimal(totalAmount / (periods.size() - 1)).setScale(0, RoundingMode.HALF_DOWN);
|
||||
BigDecimal lastExpectedAmount = new BigDecimal(totalAmount).setScale(0, RoundingMode.HALF_DOWN);
|
||||
|
||||
for (int i = 1; i < periods.size(); i++) {
|
||||
BigDecimal actualAmount = new BigDecimal(periods.get(i).getPrincipalOriginalDue()).setScale(0, RoundingMode.HALF_DOWN);
|
||||
|
||||
if (i == periods.size() - 1) {
|
||||
assertThat(actualAmount.compareTo(lastExpectedAmount))
|
||||
.as(ErrorMessageHelper.wrongAmountInRepaymentSchedule(i, actualAmount, lastExpectedAmount)).isEqualTo(0);
|
||||
} else {
|
||||
assertThat(actualAmount.compareTo(expectedAmount))
|
||||
.as(ErrorMessageHelper.wrongAmountInRepaymentSchedule(i, actualAmount, expectedAmount)).isEqualTo(0);
|
||||
lastExpectedAmount = lastExpectedAmount.subtract(actualAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@When("Customer adjust {string}th repayment on {string} with amount {string} and check external owner")
|
||||
public void adjustNthRepaymentWithExternalOwner(String nthItemStr, String transactionDate, String amount) throws IOException {
|
||||
String transferExternalOwnerId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_OWNER_EXTERNAL_ID);
|
||||
adjustNthRepaymentWithExternalOwnerCheck(nthItemStr, transactionDate, amount, transferExternalOwnerId);
|
||||
}
|
||||
|
||||
@When("Customer adjust {string}th repayment on {string} with amount {string}")
|
||||
public void adjustNthRepayment(String nthItemStr, String transactionDate, String amount) throws IOException {
|
||||
adjustNthRepaymentWithExternalOwnerCheck(nthItemStr, transactionDate, amount, null);
|
||||
}
|
||||
|
||||
private void adjustNthRepaymentWithExternalOwnerCheck(String nthItemStr, String transactionDate, String amount, String externalOwnerId)
|
||||
throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
List<GetLoansLoanIdTransactions> transactions = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute().body()
|
||||
.getTransactions();
|
||||
|
||||
int nthItem = Integer.parseInt(nthItemStr) - 1;
|
||||
GetLoansLoanIdTransactions targetTransaction = transactions.stream().filter(t -> Boolean.TRUE.equals(t.getType().getRepayment()))
|
||||
.toList().get(nthItem);
|
||||
double amountValue = Double.parseDouble(amount);
|
||||
PostLoansLoanIdTransactionsTransactionIdRequest repaymentUndoRequest = LoanRequestFactory.defaultRepaymentAdjustRequest(amountValue)
|
||||
.transactionDate(transactionDate).dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> repaymentAdjustmentResponse = loanTransactionsApi
|
||||
.adjustLoanTransaction(loanId, targetTransaction.getId(), repaymentUndoRequest, "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(repaymentAdjustmentResponse);
|
||||
testContext().set(TestContextKey.LOAN_REPAYMENT_UNDO_RESPONSE, repaymentAdjustmentResponse);
|
||||
|
||||
EventAssertion.EventAssertionBuilder<LoanTransactionAdjustmentDataV1> eventAssertionBuilder = eventAssertion
|
||||
.assertEvent(LoanAdjustTransactionBusinessEvent.class, targetTransaction.getId());
|
||||
eventAssertionBuilder
|
||||
.extractingData(loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getId())
|
||||
.isEqualTo(targetTransaction.getId());
|
||||
eventAssertionBuilder.extractingData(
|
||||
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getAmount().doubleValue())
|
||||
.isEqualTo(targetTransaction.getAmount());
|
||||
eventAssertionBuilder
|
||||
.extractingData(
|
||||
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getManuallyReversed())
|
||||
.isEqualTo(Boolean.TRUE);
|
||||
eventAssertionBuilder
|
||||
.extractingData(
|
||||
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getTransactionToAdjust().getExternalOwnerId())
|
||||
.isEqualTo(externalOwnerId);
|
||||
if (amountValue > 0) {
|
||||
eventAssertionBuilder
|
||||
.extractingData(loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getNewTransactionDetail().getId())
|
||||
.isEqualTo(repaymentAdjustmentResponse.body().getResourceId());
|
||||
eventAssertionBuilder.extractingData(
|
||||
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getNewTransactionDetail().getAmount().doubleValue())
|
||||
.isEqualTo(amountValue);
|
||||
eventAssertionBuilder.extractingData(
|
||||
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getNewTransactionDetail().getExternalOwnerId())
|
||||
.isEqualTo(externalOwnerId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.test.stepdef.loan;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.cucumber.datatable.DataTable;
|
||||
import io.cucumber.java.en.Then;
|
||||
import io.cucumber.java.en.When;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.client.models.PostCreateRescheduleLoansRequest;
|
||||
import org.apache.fineract.client.models.PostCreateRescheduleLoansResponse;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.models.PostUpdateRescheduleLoansRequest;
|
||||
import org.apache.fineract.client.models.PostUpdateRescheduleLoansResponse;
|
||||
import org.apache.fineract.client.services.RescheduleLoansApi;
|
||||
import org.apache.fineract.client.util.JSON;
|
||||
import org.apache.fineract.test.data.LoanRescheduleErrorMessage;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.helper.ErrorMessageHelper;
|
||||
import org.apache.fineract.test.helper.ErrorResponse;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.apache.fineract.test.support.TestContextKey;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import retrofit2.Response;
|
||||
|
||||
@Slf4j
|
||||
public class LoanRescheduleStepDef extends AbstractStepDef {
|
||||
|
||||
private static final Gson GSON = new JSON().getGson();
|
||||
|
||||
@Autowired
|
||||
private RescheduleLoansApi rescheduleLoansApi;
|
||||
|
||||
@When("Admin creates and approves Loan reschedule with the following data:")
|
||||
public void createAndApproveLoanReschedule(DataTable table) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
List<List<String>> data = table.asLists();
|
||||
List<String> rescheduleData = data.get(1);
|
||||
String rescheduleFromDate = rescheduleData.get(0);
|
||||
String submittedOnDate = rescheduleData.get(1);
|
||||
String adjustedDueDate = rescheduleData.get(2);
|
||||
Integer graceOfPrincipal = Integer.parseInt(rescheduleData.get(3)) == 0 ? null : Integer.valueOf(rescheduleData.get(3));
|
||||
Integer graceOnInterest = Integer.parseInt(rescheduleData.get(4)) == 0 ? null : Integer.valueOf(rescheduleData.get(4));
|
||||
Integer extraTerms = Integer.parseInt(rescheduleData.get(5)) == 0 ? null : Integer.valueOf(rescheduleData.get(5));
|
||||
BigDecimal newInterestRate = new BigDecimal(rescheduleData.get(6));
|
||||
|
||||
PostCreateRescheduleLoansRequest request = new PostCreateRescheduleLoansRequest()//
|
||||
.loanId(loanId)//
|
||||
.rescheduleFromDate(rescheduleFromDate)//
|
||||
.submittedOnDate(submittedOnDate)//
|
||||
.adjustedDueDate(adjustedDueDate)//
|
||||
.graceOnPrincipal(graceOfPrincipal)//
|
||||
.graceOnInterest(graceOnInterest)//
|
||||
.extraTerms(extraTerms)//
|
||||
.newInterestRate(newInterestRate)//
|
||||
.rescheduleReasonId(54L)//
|
||||
.rescheduleReasonComment("")//
|
||||
.dateFormat("dd MMMM yyyy")//
|
||||
.locale("en");//
|
||||
|
||||
Response<PostCreateRescheduleLoansResponse> createResponse = rescheduleLoansApi.createLoanRescheduleRequest(request).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(createResponse);
|
||||
|
||||
Long scheduleId = createResponse.body().getResourceId();
|
||||
PostUpdateRescheduleLoansRequest approveRequest = new PostUpdateRescheduleLoansRequest()//
|
||||
.approvedOnDate(submittedOnDate)//
|
||||
.dateFormat("dd MMMM yyyy")//
|
||||
.locale("en");//
|
||||
|
||||
Response<PostUpdateRescheduleLoansResponse> approveResponse = rescheduleLoansApi
|
||||
.updateLoanRescheduleRequest(scheduleId, approveRequest, "approve").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(approveResponse);
|
||||
}
|
||||
|
||||
@Then("Loan reschedule with the following data results a {int} error and {string} error message")
|
||||
public void createLoanRescheduleError(int errorCodeExpected, String errorMessageType, DataTable table) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
List<List<String>> data = table.asLists();
|
||||
List<String> rescheduleData = data.get(1);
|
||||
String rescheduleFromDate = rescheduleData.get(0);
|
||||
String submittedOnDate = rescheduleData.get(1);
|
||||
String adjustedDueDate = rescheduleData.get(2);
|
||||
Integer graceOfPrincipal = Integer.parseInt(rescheduleData.get(3)) == 0 ? null : Integer.valueOf(rescheduleData.get(3));
|
||||
Integer graceOnInterest = Integer.parseInt(rescheduleData.get(4)) == 0 ? null : Integer.valueOf(rescheduleData.get(4));
|
||||
Integer extraTerms = Integer.parseInt(rescheduleData.get(5)) == 0 ? null : Integer.valueOf(rescheduleData.get(5));
|
||||
BigDecimal newInterestRate = new BigDecimal(rescheduleData.get(6));
|
||||
|
||||
PostCreateRescheduleLoansRequest request = new PostCreateRescheduleLoansRequest()//
|
||||
.loanId(loanId)//
|
||||
.rescheduleFromDate(rescheduleFromDate)//
|
||||
.submittedOnDate(submittedOnDate)//
|
||||
.adjustedDueDate(adjustedDueDate)//
|
||||
.graceOnPrincipal(graceOfPrincipal)//
|
||||
.graceOnInterest(graceOnInterest)//
|
||||
.extraTerms(extraTerms)//
|
||||
.newInterestRate(newInterestRate)//
|
||||
.rescheduleReasonId(54L)//
|
||||
.rescheduleReasonComment("")//
|
||||
.dateFormat("dd MMMM yyyy")//
|
||||
.locale("en");//
|
||||
|
||||
Response<PostCreateRescheduleLoansResponse> createResponse = rescheduleLoansApi.createLoanRescheduleRequest(request).execute();
|
||||
|
||||
LoanRescheduleErrorMessage loanRescheduleErrorMessage = LoanRescheduleErrorMessage.valueOf(errorMessageType);
|
||||
String errorMessageExpected = loanRescheduleErrorMessage.getValue(loanId);
|
||||
|
||||
String errorToString = createResponse.errorBody().string();
|
||||
ErrorResponse errorResponse = GSON.fromJson(errorToString, ErrorResponse.class);
|
||||
String errorMessageActual = errorResponse.getErrors().get(0).getDeveloperMessage();
|
||||
int errorCodeActual = createResponse.code();
|
||||
|
||||
assertThat(errorCodeActual).as(ErrorMessageHelper.wrongErrorCode(errorCodeActual, errorCodeExpected)).isEqualTo(errorCodeExpected);
|
||||
assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected))
|
||||
.isEqualTo(errorMessageExpected);
|
||||
|
||||
log.info("ERROR CODE: {}", errorCodeActual);
|
||||
log.info("ERROR MESSAGE: {}", errorMessageActual);
|
||||
}
|
||||
}
|
||||
+2093
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user