FINERACT-2326: Missing user permission for Capitalized Income and Buydown fee
This commit is contained in:
committed by
Arnold Gálovics
parent
6bbc4bd3f3
commit
18d6a7cf69
+87
@@ -82,15 +82,19 @@ import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest;
|
||||
import org.apache.fineract.client.models.PostLoansRequest;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.models.PostRolesRequest;
|
||||
import org.apache.fineract.client.models.PostUsersRequest;
|
||||
import org.apache.fineract.client.models.PutGlobalConfigurationsRequest;
|
||||
import org.apache.fineract.client.models.PutLoansApprovedAmountRequest;
|
||||
import org.apache.fineract.client.models.PutLoansApprovedAmountResponse;
|
||||
import org.apache.fineract.client.models.PutLoansAvailableDisbursementAmountRequest;
|
||||
import org.apache.fineract.client.models.PutLoansAvailableDisbursementAmountResponse;
|
||||
import org.apache.fineract.client.models.PutLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.PutRolesRoleIdPermissionsRequest;
|
||||
import org.apache.fineract.client.models.RetrieveLoansPointInTimeRequest;
|
||||
import org.apache.fineract.client.util.CallFailedRuntimeException;
|
||||
import org.apache.fineract.client.util.Calls;
|
||||
import org.apache.fineract.client.util.FineractClient;
|
||||
import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants;
|
||||
import org.apache.fineract.infrastructure.event.external.data.ExternalEventResponse;
|
||||
import org.apache.fineract.integrationtests.client.IntegrationTest;
|
||||
@@ -126,12 +130,15 @@ import org.hamcrest.Matcher;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Response;
|
||||
|
||||
@Slf4j
|
||||
@ExtendWith({ LoanTestLifecycleExtension.class, ExternalEventsExtension.class })
|
||||
public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
|
||||
protected static final String DATETIME_PATTERN = "dd MMMM yyyy";
|
||||
protected static final String LOCALE = "en";
|
||||
|
||||
static {
|
||||
Utils.initializeRESTAssured();
|
||||
@@ -305,6 +312,86 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
return repaymentId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a Loan transaction request by a user created with no permissions then verifies it fails with
|
||||
* authentication error. Then alters user permissions to get the given permission then executes the query again. It
|
||||
* verifies that it returns with no error.
|
||||
*
|
||||
* @param loanId
|
||||
* loan id
|
||||
* @param postLoansLoanIdTransactionsRequest
|
||||
* transaction request
|
||||
* @param command
|
||||
* the command for loan transaction
|
||||
* @param permission
|
||||
* the given permission related to the loan transaction
|
||||
* @return Result body
|
||||
*/
|
||||
public PostLoansLoanIdTransactionsResponse makeLoanTransactionWithPermissionVerification(final Long loanId,
|
||||
PostLoansLoanIdTransactionsRequest postLoansLoanIdTransactionsRequest, final String command, final String permission) {
|
||||
return performPermissionTestForRequest(permission, fineractClient -> fineractClient.loanTransactions.executeLoanTransaction(loanId,
|
||||
postLoansLoanIdTransactionsRequest, command));
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a Loan transaction adjustment request by a user created with no permissions then verifies it fails with
|
||||
* authentication error. Then alters user permissions to get the given permission then executes the query again. It
|
||||
* verifies that it returns with no error.
|
||||
*
|
||||
* @param loanId
|
||||
* loan ID
|
||||
* @param transactionIdToAdjust
|
||||
* transaction ID to adjust
|
||||
* @param postLoansLoanIdTransactionsRequest
|
||||
* transaction request
|
||||
* @param command
|
||||
* the command for loan transaction
|
||||
* @param permission
|
||||
* the given permission related to the loan transaction
|
||||
* @return Result body
|
||||
*/
|
||||
public PostLoansLoanIdTransactionsResponse adjustLoanTransactionWithPermissionVerification(final Long loanId,
|
||||
final Long transactionIdToAdjust, PostLoansLoanIdTransactionsTransactionIdRequest postLoansLoanIdTransactionsRequest,
|
||||
final String command, final String permission) {
|
||||
return performPermissionTestForRequest(permission, fineractClient -> fineractClient.loanTransactions.adjustLoanTransaction(loanId,
|
||||
transactionIdToAdjust, postLoansLoanIdTransactionsRequest, command));
|
||||
}
|
||||
|
||||
public <T> T performPermissionTestForRequest(final String permission, Function<FineractClient, Call<T>> callback) {
|
||||
// create role
|
||||
String roleName = Utils.uniqueRandomStringGenerator("TEST_ROLE_", 10);
|
||||
Long roleId = Calls
|
||||
.ok(fineractClient().roles.createRole(new PostRolesRequest().name(roleName).description("Test role Description")))
|
||||
.getResourceId();
|
||||
|
||||
Calls.ok(fineractClient().roles.updateRolePermissions(roleId,
|
||||
new PutRolesRoleIdPermissionsRequest().putPermissionsItem(permission, false)));
|
||||
// create user with role
|
||||
String firstname = "Test";
|
||||
String lastname = Utils.uniqueRandomStringGenerator("User", 6);
|
||||
String userName = Utils.uniqueRandomStringGenerator("testUserName", 4);
|
||||
String password = "AKleRbDhK421$";
|
||||
String email = firstname + "." + lastname + "@whatever.mifos.org";
|
||||
Calls.ok(fineractClient().users
|
||||
.create15(new PostUsersRequest().addRolesItem(roleId).email(email).firstname(firstname).lastname(lastname)
|
||||
.repeatPassword(password).sendPasswordToEmail(false).officeId(1L).username(userName).password(password)));
|
||||
|
||||
// login user
|
||||
FineractClient fineractClientOfUser = newFineractClient(userName, password);
|
||||
|
||||
// try to make transaction - should fail
|
||||
Response<T> responseFail = Calls.executeU(callback.apply(fineractClientOfUser));
|
||||
Assertions.assertEquals(403, responseFail.code());
|
||||
|
||||
// edit role to have permission for transaction
|
||||
Calls.ok(fineractClient().roles.updateRolePermissions(roleId,
|
||||
new PutRolesRoleIdPermissionsRequest().putPermissionsItem(permission, true)));
|
||||
// try to make transaction - should pass
|
||||
Response<T> responseOk = Calls.executeU(callback.apply(fineractClientOfUser));
|
||||
Assertions.assertEquals(200, responseOk.code());
|
||||
return responseOk.body();
|
||||
}
|
||||
|
||||
private String getNonByPassUserAuthKey(RequestSpecification requestSpec, ResponseSpecification responseSpec) {
|
||||
// creates the user
|
||||
UserHelper.getSimpleUserWithoutBypassPermission(requestSpec, responseSpec);
|
||||
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* 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 java.math.BigDecimal;
|
||||
import org.apache.fineract.client.models.PostLoanProductsRequest;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdRequest;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.models.PutLoansApprovedAmountRequest;
|
||||
import org.apache.fineract.client.util.Calls;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class UserLoanPermissionTest extends BaseLoanIntegrationTest {
|
||||
|
||||
Long clientId;
|
||||
Long loanProductId;
|
||||
private Long loanId;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
if (clientId == null) {
|
||||
clientId = ClientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
|
||||
}
|
||||
if (loanProductId == null) {
|
||||
loanProductId = loanProductHelper.createLoanProduct(create4IProgressiveWithCapitalizedIncome()
|
||||
.addSupportedInterestRefundTypesItem(SupportedInterestRefundTypesItem.MERCHANT_ISSUED_REFUND)
|
||||
.overAppliedCalculationType(null).overAppliedNumber(null).allowApprovedDisbursedAmountsOverApplied(false)
|
||||
.enableBuyDownFee(true).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
||||
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
|
||||
.receivableInterestAccountId(interestReceivableAccount.getAccountID().longValue())
|
||||
.receivableFeeAccountId(feeReceivableAccount.getAccountID().longValue())
|
||||
.receivablePenaltyAccountId(penaltyReceivableAccount.getAccountID().longValue())
|
||||
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
|
||||
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())
|
||||
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue())).getResourceId();
|
||||
}
|
||||
runAt("1 January 2025", () -> {
|
||||
|
||||
PostLoansResponse postLoansResponse = loanTransactionHelper
|
||||
.applyLoan(applyLP2ProgressiveLoanRequest(clientId, loanProductId, "1 January 2025", 10000.0, 12.0, 4, null));
|
||||
|
||||
loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(), approveLoanRequest(2000.0, "1 January 2025"));
|
||||
|
||||
loanId = postLoansResponse.getResourceId();
|
||||
disburseLoan(loanId, BigDecimal.valueOf(1000.0), "1 January 2025");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCapitalizedIncomeAndCapitalizedIncomeAdjustmentPermissions() {
|
||||
runAt("1 January 2025", () -> {
|
||||
Long capitalizedIncomeId = makeLoanTransactionWithPermissionVerification(loanId, new PostLoansLoanIdTransactionsRequest()
|
||||
.dateFormat(DATETIME_PATTERN).locale("en").transactionAmount(50.0).transactionDate("01 January 2025"),
|
||||
"capitalizedIncome", "CAPITALIZEDINCOME_LOAN").getResourceId();
|
||||
|
||||
adjustLoanTransactionWithPermissionVerification(
|
||||
loanId, capitalizedIncomeId, new PostLoansLoanIdTransactionsTransactionIdRequest().dateFormat(DATETIME_PATTERN)
|
||||
.locale("en").transactionAmount(50.0).transactionDate("1 January 2025"),
|
||||
"capitalizedIncomeAdjustment", "CAPITALIZEDINCOMEADJUSTMENT_LOAN");
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuyDownFeeAndBuyDownFeeAdjustmentPermissions() {
|
||||
runAt("1 January 2025", () -> {
|
||||
final Long buyDownFeeTransactionId = makeLoanTransactionWithPermissionVerification(loanId,
|
||||
new PostLoansLoanIdTransactionsRequest().dateFormat(DATETIME_PATTERN).transactionDate("01 January 2025").locale("en")
|
||||
.transactionAmount(100.0d),
|
||||
"buyDownFee", "BUYDOWNFEE_LOAN").getResourceId();
|
||||
|
||||
adjustLoanTransactionWithPermissionVerification(
|
||||
loanId, buyDownFeeTransactionId, new PostLoansLoanIdTransactionsTransactionIdRequest().dateFormat(DATETIME_PATTERN)
|
||||
.transactionDate("01 January 2025").locale("en").transactionAmount(100.0d),
|
||||
"buyDownFeeAdjustment", "BUYDOWNFEEADJUSTMENT_LOAN");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManualInterestRefundPermission() {
|
||||
runAt("1 February 2025", () -> {
|
||||
final Long merchantIssuedRefundId = loanTransactionHelper
|
||||
.makeMerchantIssuedRefund(loanId,
|
||||
new PostLoansLoanIdTransactionsRequest().dateFormat(DATETIME_PATTERN).locale("en")
|
||||
.transactionDate("01 February 2025").transactionAmount(100.0D).interestRefundCalculation(false))
|
||||
.getResourceId();
|
||||
|
||||
performPermissionTestForRequest("MANUAL_INTEREST_REFUND_TRANSACTION_LOAN",
|
||||
fineractClient -> fineractClient.loanTransactions.adjustLoanTransaction(loanId, merchantIssuedRefundId,
|
||||
new PostLoansLoanIdTransactionsTransactionIdRequest().dateFormat(DATETIME_PATTERN).locale("en")
|
||||
.transactionAmount(1.20D),
|
||||
"interest-refund"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateApprovedAmountPermission() {
|
||||
runAt("1 January 2025", () -> {
|
||||
// disbursement should be rejected upon validation error
|
||||
Response<PostLoansLoanIdResponse> response = Calls.executeU(
|
||||
fineractClient().loans.stateTransitions(loanId, new PostLoansLoanIdRequest().actualDisbursementDate("1 January 2025")
|
||||
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(2000.0)).locale("en"), "disburse"));
|
||||
|
||||
Assertions.assertEquals(403, response.code());
|
||||
|
||||
// update approved amount
|
||||
performPermissionTestForRequest("UPDATE_APPROVED_AMOUNT_LOAN",
|
||||
fineractClient -> fineractClient.loans.modifyLoanApprovedAmount(loanId,
|
||||
new PutLoansApprovedAmountRequest().amount(BigDecimal.valueOf(4000.0d)).locale("en")));
|
||||
|
||||
// disbursement should be performed without error
|
||||
Calls.ok(fineractClient().loans.stateTransitions(loanId, new PostLoansLoanIdRequest().actualDisbursementDate("1 January 2025")
|
||||
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(2000.0)).locale("en"), "disburse"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContractTerminationAndUndoContractTerminationPermission() {
|
||||
|
||||
runAt("2 January 2025", () -> {
|
||||
performPermissionTestForRequest("CONTRACT_TERMINATION_LOAN", fineractClient -> fineractClient.loans.stateTransitions(loanId,
|
||||
new PostLoansLoanIdRequest().note(""), "contractTermination"));
|
||||
|
||||
performPermissionTestForRequest("CONTRACT_TERMINATION_UNDO_LOAN",
|
||||
fineractClient -> fineractClient.loans.stateTransitions(loanId,
|
||||
new PostLoansLoanIdRequest().note("Contract Termination Undo Test Note"), "undoContractTermination"));
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user