[FINERACT-1965] Change date resolvement from SMART to STRICT

This commit is contained in:
taskain7
2023-08-09 00:08:26 +02:00
parent 38872a036f
commit b27653c055
19 changed files with 403 additions and 51 deletions
@@ -544,7 +544,7 @@ public class AccountingScenarioIntegrationTest {
LOG.info("--------------------------------APPLYING FOR FIXED DEPOSIT ACCOUNT --------------------------------");
final String fixedDepositApplicationJSON = new FixedDepositAccountHelper(requestSpec, responseSpec) //
.withSubmittedOnDate(submittedOnDate).build(clientID, productID, penalInterestType);
return FixedDepositAccountHelper.applyFixedDepositApplication(fixedDepositApplicationJSON, requestSpec, responseSpec);
return FixedDepositAccountHelper.applyFixedDepositApplicationGetId(fixedDepositApplicationJSON, requestSpec, responseSpec);
}
private Integer createRecurringDepositProduct(final String validFrom, final String validTo, Account... accounts) {
@@ -0,0 +1,229 @@
/**
* 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.integrationtests;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.http.ContentType;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.PostClientsRequest;
import org.apache.fineract.client.models.PostClientsResponse;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.accounting.Account;
import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
import org.apache.fineract.integrationtests.common.fixeddeposit.FixedDepositAccountHelper;
import org.apache.fineract.integrationtests.common.fixeddeposit.FixedDepositProductHelper;
import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
import org.apache.fineract.integrationtests.interoperation.InteropHelper;
import org.apache.fineract.interoperation.domain.InteropInitiatorType;
import org.apache.fineract.interoperation.domain.InteropTransactionRole;
import org.apache.fineract.interoperation.domain.InteropTransactionScenario;
import org.apache.fineract.interoperation.util.InteropUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@Slf4j
public class DateValidationTest {
public static final String WHOLE_TERM = "1";
public static final String MINIMUM_OPENING_BALANCE = "1000.0";
public static final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL";
private ResponseSpecification responseSpec;
private ResponseSpecification errorResponseSpec;
private RequestSpecification requestSpec;
private ClientHelper clientHelper;
private LoanTransactionHelper loanTransactionHelper;
private InteropHelper interopHelper;
private AccountHelper accountHelper;
@BeforeEach
public void setup() {
Utils.initializeRESTAssured();
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
this.errorResponseSpec = new ResponseSpecBuilder().expectStatusCode(400).build();
this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec);
this.loanTransactionHelper = new LoanTransactionHelper(requestSpec, responseSpec);
this.interopHelper = new InteropHelper(requestSpec, errorResponseSpec);
this.accountHelper = new AccountHelper(requestSpec, responseSpec);
}
@Test
public void testShouldFailIfDateIsInvalid() {
String invalidDate = "31 June 2022";
PostClientsRequest postClientsRequest = ClientHelper.defaultClientCreationRequest();
PostClientsResponse client = clientHelper.createClient(postClientsRequest);
Long clientId = client.getClientId();
final String loanProductJSON = new LoanProductTestBuilder().withPrincipal("1000").withRepaymentTypeAsMonth()
.withRepaymentAfterEvery("1").withNumberOfRepayments("1").withRepaymentTypeAsMonth().withinterestRatePerPeriod("0")
.withInterestRateFrequencyTypeAsMonths().withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsDecliningBalance()
.withAccountingRuleAsNone().withInterestCalculationPeriodTypeAsRepaymentPeriod(true).withDaysInMonth("30")
.withDaysInYear("365").withMoratorium("0", "0").withInArrearsTolerance("1001").withMultiDisburse()
.withDisallowExpectedDisbursements(true).build(null);
final Integer loanProductID = loanTransactionHelper.getLoanProductId(loanProductJSON);
loanTransactionHelper = new LoanTransactionHelper(requestSpec, errorResponseSpec);
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal("1000").withLoanTermFrequency("1")
.withLoanTermFrequencyAsMonths().withNumberOfRepayments("1").withRepaymentEveryAfter("1")
.withRepaymentFrequencyTypeAsMonths().withInterestRatePerPeriod("0").withInterestTypeAsFlatBalance()
.withAmortizationTypeAsEqualPrincipalPayments().withInterestCalculationPeriodTypeSameAsRepaymentPeriod()
.withExpectedDisbursementDate(invalidDate).withSubmittedOnDate("01 March 2022").withLoanType("individual")
.build(clientId.toString(), loanProductID.toString(), null);
HashMap<String, Object> response = (HashMap) loanTransactionHelper.createLoanAccount(loanApplicationJSON, "");
List<HashMap<String, Object>> errors = (List) response.get("errors");
assertNotNull(errors);
HashMap<String, Object> error = errors.get(0);
assertNotNull(error);
assertEquals(
"The parameter `expectedDisbursementDate` is invalid based on the dateFormat: `dd MMMM uuuu` and locale: `en_GB` provided:",
error.get("developerMessage"));
}
@Test
public void testShouldFailWithInvalidDateTime() {
String requestCode = UUID.randomUUID().toString();
InteropTransactionRole role = InteropTransactionRole.PAYER;
String requestBody = buildRequestBody(requestCode, role);
String response = interopHelper.postTransactionRequest(requestCode, role, requestBody);
HashMap<String, Object> map = new Gson().fromJson(response, new TypeToken<HashMap<String, Object>>() {}.getType());
List<Map<String, Object>> errors = (List) map.get("errors");
assertNotNull(errors);
Map<String, Object> error = errors.get(0);
assertNotNull(error);
assertEquals("The parameter `expiration` is invalid based on the dateFormat: `dd MMMM uuuu HH:mm:ss` and locale: `en` provided:",
error.get("developerMessage"));
}
@Test
public void testShouldFailWithInvalidMonthDay() {
final Account assetAccount = this.accountHelper.createAssetAccount();
final Account incomeAccount = this.accountHelper.createIncomeAccount();
final Account expenseAccount = this.accountHelper.createExpenseAccount();
final Account liabilityAccount = this.accountHelper.createLiabilityAccount();
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("dd MMMM yyyy").toFormatter(Locale.US);
LocalDate todaysDate = LocalDate.now(ZoneId.systemDefault()).minusMonths(3);
final String VALID_FROM = todaysDate.format(formatter);
todaysDate = todaysDate.plusYears(10);
final String VALID_TO = todaysDate.format(formatter);
todaysDate = LocalDate.now(ZoneId.systemDefault()).minusMonths(1);
final String SUBMITTED_ON_DATE = todaysDate.format(formatter);
PostClientsRequest postClientsRequest = ClientHelper.defaultClientCreationRequest();
Long clientId = clientHelper.createClient(postClientsRequest).getClientId();
Assertions.assertNotNull(clientId);
Integer fixedDepositProductId = createFixedDepositProduct(VALID_FROM, VALID_TO, assetAccount, liabilityAccount, incomeAccount,
expenseAccount);
Assertions.assertNotNull(fixedDepositProductId);
final Integer maturityInstructionId = 400;
String response = applyForFixedDepositApplication(clientId.toString(), fixedDepositProductId.toString(), SUBMITTED_ON_DATE,
maturityInstructionId, getCharges());
HashMap<String, Object> map = new Gson().fromJson(response, new TypeToken<HashMap<String, Object>>() {}.getType());
List<Map<String, Object>> errors = (List) map.get("errors");
assertNotNull(errors);
Map<String, Object> error = errors.get(0);
assertNotNull(error);
assertEquals("The parameter `feeOnMonthDay` is invalid based on the monthDayFormat: `dd MMM` and locale: `en_GB` provided:",
error.get("developerMessage"));
}
private String buildRequestBody(final String requestCode, final InteropTransactionRole role) {
HashMap<String, Object> map = new HashMap<>();
map.put(InteropUtil.PARAM_TRANSACTION_CODE, UUID.randomUUID().toString());
map.put(InteropUtil.PARAM_REQUEST_CODE, requestCode);
map.put(InteropUtil.PARAM_ACCOUNT_ID, UUID.randomUUID().toString());
map.put(InteropUtil.PARAM_TRANSACTION_ROLE, role);
map.put(InteropUtil.PARAM_EXPIRATION, "31 November 2022 11:11:11");
map.put(InteropUtil.PARAM_LOCALE, "en");
map.put(InteropUtil.PARAM_DATE_FORMAT, "dd MMMM yyyy HH:mm:ss");
HashMap<String, Object> amountMap = new HashMap<>();
amountMap.put(InteropUtil.PARAM_AMOUNT, "10");
amountMap.put(InteropUtil.PARAM_CURRENCY, "EUR");
map.put(InteropUtil.PARAM_AMOUNT, amountMap);
HashMap<String, Object> typeMap = new HashMap<>();
typeMap.put(InteropUtil.PARAM_SCENARIO, InteropTransactionScenario.PAYMENT);
typeMap.put(InteropUtil.PARAM_INITIATOR, InteropTransactionRole.PAYEE);
typeMap.put(InteropUtil.PARAM_INITIATOR_TYPE, InteropInitiatorType.CONSUMER);
map.put(InteropUtil.PARAM_TRANSACTION_TYPE, typeMap);
return new Gson().toJson(map);
}
private Integer createFixedDepositProduct(final String validFrom, final String validTo, Account... accounts) {
log.info("------------------------------CREATING NEW FIXED DEPOSIT PRODUCT ---------------------------------------");
FixedDepositProductHelper fixedDepositProductHelper = new FixedDepositProductHelper(this.requestSpec, this.responseSpec);
fixedDepositProductHelper = fixedDepositProductHelper.withAccountingRuleAsCashBased(accounts);
final String fixedDepositProductJSON = fixedDepositProductHelper.withPeriodRangeChart() //
.build(validFrom, validTo, true);
return FixedDepositProductHelper.createFixedDepositProduct(fixedDepositProductJSON, requestSpec, responseSpec);
}
private String applyForFixedDepositApplication(final String clientID, final String productID, final String submittedOnDate,
final Integer maturityInstructionId, final List<HashMap<String, String>> charges) {
log.info("--------------------------------APPLYING FOR FIXED DEPOSIT ACCOUNT --------------------------------");
final String fixedDepositApplicationJSON = new FixedDepositAccountHelper(this.requestSpec, this.errorResponseSpec) //
.withSubmittedOnDate(submittedOnDate).withMaturityInstructionId(maturityInstructionId).withCharges(charges)
.build(clientID, productID, WHOLE_TERM);
return FixedDepositAccountHelper.applyFixedDepositApplication(fixedDepositApplicationJSON, this.requestSpec,
this.errorResponseSpec);
}
private List<HashMap<String, String>> getCharges() {
List<HashMap<String, String>> list = new ArrayList<>();
HashMap<String, String> map = new HashMap<>();
map.put("feeOnMonthDay", "31 June");
list.add(map);
return list;
}
}
@@ -2584,7 +2584,8 @@ public class FixedDepositTest {
log.info("--------------------------------APPLYING FOR FIXED DEPOSIT ACCOUNT --------------------------------");
final String fixedDepositApplicationJSON = new FixedDepositAccountHelper(this.requestSpec, this.responseSpec) //
.withSubmittedOnDate(submittedOnDate).build(clientID, productID, penalInterestType);
return FixedDepositAccountHelper.applyFixedDepositApplication(fixedDepositApplicationJSON, this.requestSpec, this.responseSpec);
return FixedDepositAccountHelper.applyFixedDepositApplicationGetId(fixedDepositApplicationJSON, this.requestSpec,
this.responseSpec);
}
private Integer applyForFixedDepositApplication(final String clientID, final String productID, final String submittedOnDate,
@@ -2593,7 +2594,8 @@ public class FixedDepositTest {
final String fixedDepositApplicationJSON = new FixedDepositAccountHelper(this.requestSpec, this.responseSpec) //
.withSubmittedOnDate(submittedOnDate).withMaturityInstructionId(maturityInstructionId)
.build(clientID, productID, penalInterestType);
return FixedDepositAccountHelper.applyFixedDepositApplication(fixedDepositApplicationJSON, this.requestSpec, this.responseSpec);
return FixedDepositAccountHelper.applyFixedDepositApplicationGetId(fixedDepositApplicationJSON, this.requestSpec,
this.responseSpec);
}
private Integer applyForFixedDepositApplication(final String clientID, final String productID, final String submittedOnDate,
@@ -2603,7 +2605,8 @@ public class FixedDepositTest {
//
.withSubmittedOnDate(submittedOnDate).withDepositPeriod(depositPeriod).withDepositAmount(depositAmount)
.build(clientID, productID, penalInterestType);
return FixedDepositAccountHelper.applyFixedDepositApplication(fixedDepositApplicationJSON, this.requestSpec, this.responseSpec);
return FixedDepositAccountHelper.applyFixedDepositApplicationGetId(fixedDepositApplicationJSON, this.requestSpec,
this.responseSpec);
}
private Integer createSavingsProduct(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
@@ -1288,7 +1288,7 @@ public class SchedulerJobsTestResults {
final String fixedDepositApplicationJSON = new FixedDepositAccountHelper(requestSpec, responseSpec)
.withSubmittedOnDate(submittedOnDate).withSavings(savingsId).transferInterest(true)
.withLockinPeriodFrequency("1", FixedDepositAccountHelper.DAYS).build(clientID, productID, penalInterestType);
return FixedDepositAccountHelper.applyFixedDepositApplication(fixedDepositApplicationJSON, requestSpec, responseSpec);
return FixedDepositAccountHelper.applyFixedDepositApplicationGetId(fixedDepositApplicationJSON, requestSpec, responseSpec);
}
private void validateNumberForEqualExcludePrecision(String val, String val2) {
@@ -24,6 +24,7 @@ import io.restassured.specification.ResponseSpecification;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import org.apache.fineract.integrationtests.common.CommonConstants;
import org.apache.fineract.integrationtests.common.Utils;
import org.slf4j.Logger;
@@ -97,6 +98,7 @@ public class FixedDepositAccountHelper {
private String savingsId = null;
private boolean transferInterest = false;
private Integer maturityInstructionId;
private List<HashMap<String, String>> charges;
public String build(final String clientId, final String productId, final String penalInterestType) {
final HashMap<String, Object> map = new HashMap<>();
@@ -129,19 +131,26 @@ public class FixedDepositAccountHelper {
map.put("linkAccountId", savingsId);
map.put("transferInterestToSavings", transferInterest);
map.put("maturityInstructionId", maturityInstructionId);
map.put("charges", charges);
String fixedDepositAccountJson = new Gson().toJson(map);
LOG.info("{}", fixedDepositAccountJson);
return fixedDepositAccountJson;
}
public static Integer applyFixedDepositApplication(final String fixedDepositAccountAsJson, final RequestSpecification requestSpec,
public static Integer applyFixedDepositApplicationGetId(final String fixedDepositAccountAsJson, final RequestSpecification requestSpec,
final ResponseSpecification responseSpec) {
LOG.info("--------------------- APPLYING FOR FIXED DEPOSIT ACCOUNT ------------------------");
return Utils.performServerPost(requestSpec, responseSpec, APPLY_FIXED_DEPOSIT_ACCOUNT_URL, fixedDepositAccountAsJson,
CommonConstants.RESPONSE_RESOURCE_ID);
}
public static String applyFixedDepositApplication(final String fixedDepositAccountAsJson, final RequestSpecification requestSpec,
final ResponseSpecification responseSpec) {
LOG.info("--------------------- APPLYING FOR FIXED DEPOSIT ACCOUNT ------------------------");
return Utils.performServerPost(requestSpec, responseSpec, APPLY_FIXED_DEPOSIT_ACCOUNT_URL, fixedDepositAccountAsJson);
}
public static HashMap getFixedDepositAccountById(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer accountID) {
final String GET_FIXED_DEPOSIT_BY_ID_URL = FIXED_DEPOSIT_ACCOUNT_URL + "/" + accountID + "?" + Utils.TENANT_IDENTIFIER;
@@ -475,4 +484,9 @@ public class FixedDepositAccountHelper {
this.maturityInstructionId = maturityInstructionId;
return this;
}
public FixedDepositAccountHelper withCharges(List<HashMap<String, String>> charges) {
this.charges = charges;
return this;
}
}
@@ -214,6 +214,15 @@ public class InteropHelper {
return response;
}
public String postTransactionRequest(String requestCode, InteropTransactionRole role, String request) {
String url = buildUrl(REQUESTS_URL);
LOG.debug("Calling Interoperable POST Request: {}, body: {}", url, request);
String response = Utils.performServerPost(requestSpec, responseSpec, url, request, null);
LOG.debug("Response Interoperable POST Request: {}", response);
return response;
}
private String buildTransactionRequestJson(String requestCode, InteropTransactionRole role) {
HashMap<String, Object> map = new HashMap<>();
map.put(InteropUtil.PARAM_TRANSACTION_CODE, transactionCode);