Fine tuning the batch APIs and minor adjustments
This commit is contained in:
committed by
Arnold Gálovics
parent
a89fe53937
commit
77fd4ff4c1
+134
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* 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.batch.command;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import org.apache.fineract.batch.command.internal.ActivateClientCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.ApplyLoanCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.ApplySavingsCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.ApproveLoanCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.ApproveLoanRescheduleCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.CollectChargesCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.CreateChargeCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.CreateClientCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.DisburseLoanCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.GetLoanByIdCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.GetTransactionByIdCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.RepayLoanCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.UnknownCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.UpdateClientCommandStrategy;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* Tests {@link CommandStrategyProvider}.
|
||||
*/
|
||||
public class CommandStrategyProviderTest {
|
||||
|
||||
/**
|
||||
* Command strategy provider.
|
||||
*
|
||||
* @return the test data stream
|
||||
*/
|
||||
private static Stream<Arguments> provideCommandStrategies() {
|
||||
return Stream.of(Arguments.of("clients", HttpMethod.POST, "createClientCommandStrategy", mock(CreateClientCommandStrategy.class)),
|
||||
Arguments.of("clients/123", HttpMethod.PUT, "updateClientCommandStrategy", mock(UpdateClientCommandStrategy.class)),
|
||||
Arguments.of("loans", HttpMethod.POST, "applyLoanCommandStrategy", mock(ApplyLoanCommandStrategy.class)),
|
||||
Arguments.of("loans/123", HttpMethod.GET, "getLoanByIdCommandStrategy", mock(GetLoanByIdCommandStrategy.class)),
|
||||
Arguments.of("loans/123?associations=all", HttpMethod.GET, "getLoanByIdCommandStrategy",
|
||||
mock(GetLoanByIdCommandStrategy.class)),
|
||||
Arguments.of("loans/123?associations=all&exclude=guarantors", HttpMethod.GET, "getLoanByIdCommandStrategy",
|
||||
mock(GetLoanByIdCommandStrategy.class)),
|
||||
Arguments.of("savingsaccounts", HttpMethod.POST, "applySavingsCommandStrategy", mock(ApplySavingsCommandStrategy.class)),
|
||||
Arguments.of("loans/123/charges", HttpMethod.POST, "createChargeCommandStrategy", mock(CreateChargeCommandStrategy.class)),
|
||||
Arguments.of("loans/123/charges", HttpMethod.GET, "collectChargesCommandStrategy",
|
||||
mock(CollectChargesCommandStrategy.class)),
|
||||
Arguments.of("loans/123/transactions?command=repayment", HttpMethod.POST, "repayLoanCommandStrategy",
|
||||
mock(RepayLoanCommandStrategy.class)),
|
||||
Arguments.of("clients/456?command=activate", HttpMethod.POST, "activateClientCommandStrategy",
|
||||
mock(ActivateClientCommandStrategy.class)),
|
||||
Arguments.of("loans/123?command=approve", HttpMethod.POST, "approveLoanCommandStrategy",
|
||||
mock(ApproveLoanCommandStrategy.class)),
|
||||
Arguments.of("loans/123?command=disburse", HttpMethod.POST, "disburseLoanCommandStrategy",
|
||||
mock(DisburseLoanCommandStrategy.class)),
|
||||
Arguments.of("rescheduleloans/123?command=approve", HttpMethod.POST, "approveLoanRescheduleCommandStrategy",
|
||||
mock(ApproveLoanRescheduleCommandStrategy.class)),
|
||||
Arguments.of("loans/123/transactions/123", HttpMethod.GET, "getTransactionByIdCommandStrategy",
|
||||
mock(GetTransactionByIdCommandStrategy.class)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link CommandStrategyProvider#getCommandStrategy} for success scenarios.
|
||||
*
|
||||
* @param url
|
||||
* the resource URL
|
||||
* @param httpMethod
|
||||
* the resource HTTP method
|
||||
* @param beanName
|
||||
* the context bean name
|
||||
* @param commandStrategy
|
||||
* the command strategy
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideCommandStrategies")
|
||||
public void testGetCommandStrategySuccess(final String url, final String httpMethod, final String beanName,
|
||||
final CommandStrategy commandStrategy) {
|
||||
final ApplicationContext applicationContext = mock(ApplicationContext.class);
|
||||
final CommandStrategyProvider commandStrategyProvider = new CommandStrategyProvider(applicationContext);
|
||||
when(applicationContext.getBean(beanName)).thenReturn(commandStrategy);
|
||||
|
||||
final CommandStrategy result = commandStrategyProvider.getCommandStrategy(CommandContext.resource(url).method(httpMethod).build());
|
||||
assertEquals(commandStrategy, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Command strategy provider for error scenarioss.
|
||||
*
|
||||
* @return the test data stream
|
||||
*/
|
||||
private static Stream<Arguments> provideCommandStrategyResourceDetailsForErrors() {
|
||||
return Stream.of(Arguments.of("loans/123?command=reject", HttpMethod.POST),
|
||||
Arguments.of("loans/glimAccount/746?command=approve", HttpMethod.POST), Arguments.of("loans/123", HttpMethod.PUT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link CommandStrategyProvider#getCommandStrategy} for error scenarios.
|
||||
*
|
||||
* @param url
|
||||
* the resource URL
|
||||
* @param httpMethod
|
||||
* the resource HTTP method
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideCommandStrategyResourceDetailsForErrors")
|
||||
public void testGetCommandStrategyForError(final String url, final String httpMethod) {
|
||||
final ApplicationContext applicationContext = mock(ApplicationContext.class);
|
||||
final CommandStrategyProvider commandStrategyProvider = new CommandStrategyProvider(applicationContext);
|
||||
|
||||
final CommandStrategy result = commandStrategyProvider.getCommandStrategy(CommandContext.resource(url).method(httpMethod).build());
|
||||
assertEquals(UnknownCommandStrategy.class, result.getClass());
|
||||
}
|
||||
}
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* 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.batch.command.internal;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.fineract.batch.domain.BatchRequest;
|
||||
import org.apache.fineract.batch.domain.BatchResponse;
|
||||
import org.apache.fineract.infrastructure.core.api.MutableUriInfo;
|
||||
import org.apache.fineract.portfolio.loanaccount.api.LoansApiResource;
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
public class GetLoanByIdCommandStrategyTest {
|
||||
|
||||
private static Stream<Arguments> provideQueryParameters() {
|
||||
return Stream.of(Arguments.of(null, 0), Arguments.of("associations=all", 1),
|
||||
Arguments.of("fields=id,principal,annualInterestRate&associations=repaymentSchedule,transactions", 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link GetLoanByIdCommandStrategy#execute} happy path scenario.
|
||||
*
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideQueryParameters")
|
||||
public void testExecuteSuccessScenario(final String queryParameter, final int noOfQueryParams) {
|
||||
// given
|
||||
final TestContext testContext = new TestContext();
|
||||
|
||||
final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
|
||||
final BatchRequest request = getBatchRequest(loanId, queryParameter);
|
||||
final String responseBody = "{\\\"id\\\":2,\\\"accountNo\\\":\\\"000000002\\\"}";
|
||||
|
||||
given(testContext.loansApiResource.retrieveLoan(eq(loanId), eq(false), any(UriInfo.class))).willReturn(responseBody);
|
||||
|
||||
// when
|
||||
final BatchResponse response = testContext.underTest.execute(request, testContext.uriInfo);
|
||||
|
||||
// then
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.SC_OK);
|
||||
assertThat(response.getRequestId()).isEqualTo(request.getRequestId());
|
||||
assertThat(response.getHeaders()).isEqualTo(request.getHeaders());
|
||||
assertThat(response.getBody()).isEqualTo(responseBody);
|
||||
|
||||
verify(testContext.loansApiResource).retrieveLoan(eq(loanId), eq(false), testContext.uriInfoCaptor.capture());
|
||||
MutableUriInfo mutableUriInfo = testContext.uriInfoCaptor.getValue();
|
||||
assertThat(mutableUriInfo.getAdditionalQueryParameters()).hasSize(noOfQueryParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link GetLoanByIdCommandStrategy#execute} for internal server error.
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteForInternalServerError() {
|
||||
// given
|
||||
final TestContext testContext = new TestContext();
|
||||
final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
|
||||
final BatchRequest request = getBatchRequest(loanId, null);
|
||||
|
||||
given(testContext.loansApiResource.retrieveLoan(eq(loanId), eq(false), any(UriInfo.class)))
|
||||
.willThrow(new RuntimeException("Some error"));
|
||||
|
||||
// when
|
||||
final BatchResponse response = testContext.underTest.execute(request, testContext.uriInfo);
|
||||
|
||||
// then
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.SC_INTERNAL_SERVER_ERROR);
|
||||
assertThat(response.getBody()).isEqualTo("{\"Exception\": java.lang.RuntimeException: Some error}");
|
||||
assertThat(response.getRequestId()).isEqualTo(request.getRequestId());
|
||||
assertThat(response.getHeaders()).isEqualTo(request.getHeaders());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link GetLoanByIdCommandStrategy#execute} for loan not found exception.
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteForLoanNotFoundException() {
|
||||
// given
|
||||
final TestContext testContext = new TestContext();
|
||||
final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
|
||||
final BatchRequest request = getBatchRequest(loanId, null);
|
||||
|
||||
given(testContext.loansApiResource.retrieveLoan(eq(loanId), eq(false), any(UriInfo.class)))
|
||||
.willThrow(new LoanNotFoundException(loanId));
|
||||
|
||||
// when
|
||||
final BatchResponse response = testContext.underTest.execute(request, testContext.uriInfo);
|
||||
|
||||
// then
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.SC_NOT_FOUND);
|
||||
assertThat(response.getBody()).isEqualTo(buildLoanNotFoundError(loanId));
|
||||
assertThat(response.getRequestId()).isEqualTo(request.getRequestId());
|
||||
assertThat(response.getHeaders()).isEqualTo(request.getHeaders());
|
||||
}
|
||||
|
||||
private String buildLoanNotFoundError(final Long loanId) {
|
||||
return String.format(
|
||||
"{\n \"developerMessage\": \"The requested resource is not available.\",\n"
|
||||
+ " \"httpStatusCode\": \"404\",\n \"defaultUserMessage\": \"The requested resource is not available.\",\n"
|
||||
+ " \"userMessageGlobalisationCode\": \"error.msg.resource.not.found\",\n \"errors\": [\n {\n"
|
||||
+ " \"developerMessage\": \"Loan with identifier %s does not exist\",\n"
|
||||
+ " \"defaultUserMessage\": \"Loan with identifier %s does not exist\",\n"
|
||||
+ " \"userMessageGlobalisationCode\": \"error.msg.loan.id.invalid\",\n \"parameterName\": \"id\",\n"
|
||||
+ " \"args\": [\n {\n \"value\": %s\n }\n ]\n }\n ]\n" + "}",
|
||||
loanId, loanId, loanId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a request with the given loan id.
|
||||
*
|
||||
* @param loanId
|
||||
* the loan id
|
||||
* @return BatchRequest
|
||||
*/
|
||||
private BatchRequest getBatchRequest(final Long loanId, final String queryParamStr) {
|
||||
|
||||
final BatchRequest br = new BatchRequest();
|
||||
String relativeUrl = "loans/" + loanId;
|
||||
if (queryParamStr != null) {
|
||||
relativeUrl = relativeUrl + "?" + queryParamStr;
|
||||
}
|
||||
|
||||
br.setRequestId(Long.valueOf(RandomStringUtils.randomNumeric(5)));
|
||||
br.setRelativeUrl(relativeUrl);
|
||||
br.setMethod(HttpMethod.GET);
|
||||
br.setReference(Long.valueOf(RandomStringUtils.randomNumeric(5)));
|
||||
br.setBody("{}");
|
||||
|
||||
return br;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private test context class used since testng runs in parallel to avoid state between tests
|
||||
*/
|
||||
private static class TestContext {
|
||||
|
||||
@Mock
|
||||
private UriInfo uriInfo;
|
||||
|
||||
@Mock
|
||||
private LoansApiResource loansApiResource;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<MutableUriInfo> uriInfoCaptor;
|
||||
|
||||
private final GetLoanByIdCommandStrategy underTest;
|
||||
|
||||
TestContext() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
underTest = new GetLoanByIdCommandStrategy(loansApiResource);
|
||||
}
|
||||
}
|
||||
}
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
/**
|
||||
* 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.batch.command.internal;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.fineract.batch.domain.BatchRequest;
|
||||
import org.apache.fineract.batch.domain.BatchResponse;
|
||||
import org.apache.fineract.portfolio.loanaccount.api.LoanTransactionsApiResource;
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.LoanTransactionNotFoundException;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
public class GetTransactionByIdCommandStrategyTest {
|
||||
|
||||
/**
|
||||
* Test {@link GetTransactionByIdCommandStrategy#execute} happy path scenario.
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteSuccessScenario() {
|
||||
// given
|
||||
final TestContext testContext = new TestContext();
|
||||
|
||||
final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
|
||||
final Long transactionId = Long.valueOf(RandomStringUtils.randomNumeric(4));
|
||||
final BatchRequest request = getBatchRequest(loanId, transactionId);
|
||||
final String responseBody = "{\"id\":12,\"officeId\":1,\"officeName\":\"Head Office\",\"type\":{\"id\":10,\"code\":"
|
||||
+ "\"loanTransactionType.accrual\",\"value\":\"Accrual\",\"disbursement\":false,\"repaymentAtDisbursement\":false,"
|
||||
+ "\"repayment\":false,\"contra\":false,\"waiveInterest\":false,\"waiveCharges\":false,\"accrual\":true,\"writeOff\":false,"
|
||||
+ "\"recoveryRepayment\":false,\"initiateTransfer\":false,\"approveTransfer\":false,\"withdrawTransfer\":false,"
|
||||
+ "\"rejectTransfer\":false,\"chargePayment\":false,\"refund\":false,\"refundForActiveLoans\":false},\"date\":[2022,3,29],"
|
||||
+ "\"currency\":{\"code\":\"EUR\",\"name\":\"Euro\",\"decimalPlaces\":2,\"inMultiplesOf\":0,\"displaySymbol\":\"€\","
|
||||
+ "\"nameCode\":\"currency.EUR\",\"displayLabel\":\"Euro (€)\"},\"amount\":0.000000,\"netDisbursalAmount\":200.000000,"
|
||||
+ "\"principalPortion\":0,\"interestPortion\":0.000000,\"feeChargesPortion\":0,\"penaltyChargesPortion\":0,\"overpaymentPortion\":0,"
|
||||
+ "\"unrecognizedIncomePortion\":0,\"outstandingLoanBalance\":0,\"submittedOnDate\":[2022,3,29],\"manuallyReversed\":false,"
|
||||
+ "\"loanChargePaidByList\":[],\"numberOfRepayments\":0}";
|
||||
|
||||
given(testContext.loanTransactionsApiResource.retrieveTransaction(loanId, transactionId, testContext.uriInfo))
|
||||
.willReturn(responseBody);
|
||||
|
||||
// when
|
||||
final BatchResponse response = testContext.subjectToTest.execute(request, testContext.uriInfo);
|
||||
|
||||
// then
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.SC_OK);
|
||||
assertThat(response.getRequestId()).isEqualTo(request.getRequestId());
|
||||
assertThat(response.getHeaders()).isEqualTo(request.getHeaders());
|
||||
assertThat(response.getBody()).isEqualTo(responseBody);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link GetTransactionByIdCommandStrategy#execute} for internal server error.
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteForInternalServerError() {
|
||||
// given
|
||||
final TestContext testContext = new TestContext();
|
||||
final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
|
||||
final Long transactionId = Long.valueOf(RandomStringUtils.randomNumeric(4));
|
||||
final BatchRequest request = getBatchRequest(loanId, transactionId);
|
||||
|
||||
given(testContext.loanTransactionsApiResource.retrieveTransaction(loanId, transactionId, testContext.uriInfo))
|
||||
.willThrow(new RuntimeException("Some error"));
|
||||
|
||||
// when
|
||||
final BatchResponse response = testContext.subjectToTest.execute(request, testContext.uriInfo);
|
||||
|
||||
// then
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.SC_INTERNAL_SERVER_ERROR);
|
||||
assertThat(response.getRequestId()).isEqualTo(request.getRequestId());
|
||||
assertThat(response.getHeaders()).isEqualTo(request.getHeaders());
|
||||
assertThat(response.getBody()).isEqualTo("{\"Exception\": java.lang.RuntimeException: Some error}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link GetTransactionByIdCommandStrategy#execute} for loan not found exception.
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteForLoanNotFoundException() {
|
||||
// given
|
||||
final TestContext testContext = new TestContext();
|
||||
final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
|
||||
final Long transactionId = Long.valueOf(RandomStringUtils.randomNumeric(4));
|
||||
final BatchRequest request = getBatchRequest(loanId, transactionId);
|
||||
|
||||
given(testContext.loanTransactionsApiResource.retrieveTransaction(loanId, transactionId, testContext.uriInfo))
|
||||
.willThrow(new LoanNotFoundException(loanId));
|
||||
|
||||
// when
|
||||
final BatchResponse response = testContext.subjectToTest.execute(request, testContext.uriInfo);
|
||||
|
||||
// then
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.SC_NOT_FOUND);
|
||||
assertThat(response.getRequestId()).isEqualTo(request.getRequestId());
|
||||
assertThat(response.getHeaders()).isEqualTo(request.getHeaders());
|
||||
assertThat(response.getBody()).isEqualTo(build404NotFoundError("Loan", loanId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link GetTransactionByIdCommandStrategy#execute} for transaction not found exception.
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteForTransactionNotFoundException() {
|
||||
final TestContext testContext = new TestContext();
|
||||
final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
|
||||
final Long transactionId = Long.valueOf(RandomStringUtils.randomNumeric(4));
|
||||
final BatchRequest request = getBatchRequest(loanId, transactionId);
|
||||
|
||||
when(testContext.loanTransactionsApiResource.retrieveTransaction(loanId, transactionId, testContext.uriInfo))
|
||||
.thenThrow(new LoanTransactionNotFoundException(transactionId));
|
||||
|
||||
final BatchResponse response = testContext.subjectToTest.execute(request, testContext.uriInfo);
|
||||
|
||||
assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode());
|
||||
assertEquals(build404NotFoundError("Transaction", transactionId), response.getBody());
|
||||
assertEquals(request.getRequestId(), response.getRequestId());
|
||||
assertEquals(request.getHeaders(), response.getHeaders());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a request with the given loan id and transaction id.
|
||||
*
|
||||
* @param loanId
|
||||
* the loan id
|
||||
* @param transactionId
|
||||
* the transaction id
|
||||
* @return BatchRequest
|
||||
*/
|
||||
private BatchRequest getBatchRequest(final Long loanId, final Long transactionId) {
|
||||
|
||||
final BatchRequest br = new BatchRequest();
|
||||
String relativeUrl = "loans/" + loanId + "/transactions/" + transactionId;
|
||||
|
||||
br.setRequestId(Long.valueOf(RandomStringUtils.randomNumeric(5)));
|
||||
br.setRelativeUrl(relativeUrl);
|
||||
br.setMethod(HttpMethod.GET);
|
||||
br.setReference(Long.valueOf(RandomStringUtils.randomNumeric(5)));
|
||||
br.setBody("{}");
|
||||
|
||||
return br;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the 404 not found error.
|
||||
*
|
||||
* @param field
|
||||
* the field name
|
||||
* @param id
|
||||
* the id
|
||||
*/
|
||||
private String build404NotFoundError(final String field, final Long id) {
|
||||
return String.format("{\n" + " \"developerMessage\": \"The requested resource is not available.\",\n"
|
||||
+ " \"httpStatusCode\": \"404\",\n" + " \"defaultUserMessage\": \"The requested resource is not available.\",\n"
|
||||
+ " \"userMessageGlobalisationCode\": \"error.msg.resource.not.found\",\n" + " \"errors\": [\n" + " {\n"
|
||||
+ " \"developerMessage\": \"%s with identifier %s does not exist\",\n"
|
||||
+ " \"defaultUserMessage\": \"%s with identifier %s does not exist\",\n"
|
||||
+ " \"userMessageGlobalisationCode\": \"error.msg.loan.id.invalid\",\n" + " \"parameterName\": \"id\",\n"
|
||||
+ " \"args\": [\n" + " {\n" + " \"value\": %s\n" + " }\n" + " ]\n" + " }\n" + " ]\n"
|
||||
+ "}", field, id, field, id, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private test context class used since testng runs in parallel to avoid state between tests
|
||||
*/
|
||||
private static class TestContext {
|
||||
|
||||
@Mock
|
||||
private UriInfo uriInfo;
|
||||
|
||||
@Mock
|
||||
private LoanTransactionsApiResource loanTransactionsApiResource;
|
||||
|
||||
private final GetTransactionByIdCommandStrategy subjectToTest;
|
||||
|
||||
TestContext() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
subjectToTest = new GetTransactionByIdCommandStrategy(loanTransactionsApiResource);
|
||||
}
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* 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.portfolio.loanaccount.domain;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.portfolio.charge.domain.Charge;
|
||||
import org.apache.fineract.portfolio.charge.domain.ChargeCalculationType;
|
||||
import org.apache.fineract.portfolio.charge.domain.ChargePaymentMode;
|
||||
import org.apache.fineract.portfolio.charge.domain.ChargeTimeType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
/**
|
||||
* Tests {@link Loan}.
|
||||
*/
|
||||
public class LoanTest {
|
||||
|
||||
/**
|
||||
* Tests {@link Loan#getCharges()} with charges.
|
||||
*/
|
||||
@Test
|
||||
public void testGetChargesWithCharges() {
|
||||
Loan loan = new Loan();
|
||||
ReflectionTestUtils.setField(loan, "charges", Collections.singleton(buildLoanCharge()));
|
||||
|
||||
final Collection<LoanCharge> chargeIds = loan.getCharges();
|
||||
|
||||
assertEquals(1, chargeIds.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link Loan#getCharges()} with no charges.
|
||||
*/
|
||||
@Test
|
||||
public void testGetChargesWithNoCharges() {
|
||||
final Loan loan = new Loan();
|
||||
|
||||
final Collection<LoanCharge> chargeIds = loan.getCharges();
|
||||
|
||||
assertEquals(0, chargeIds.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link Loan#getCharges()} with null to make sure NPE is not thrown.
|
||||
*/
|
||||
@Test
|
||||
public void testGetChargesWithNull() {
|
||||
final Loan loan = new Loan();
|
||||
ReflectionTestUtils.setField(loan, "charges", null);
|
||||
|
||||
final Collection<LoanCharge> chargeIds = loan.getCharges();
|
||||
|
||||
assertEquals(0, chargeIds.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new loan charge.
|
||||
*
|
||||
* @return the {@link LoanCharge}
|
||||
*/
|
||||
private LoanCharge buildLoanCharge() {
|
||||
return new LoanCharge(mock(Loan.class), mock(Charge.class), new BigDecimal(100), new BigDecimal(100),
|
||||
ChargeTimeType.TRANCHE_DISBURSEMENT, ChargeCalculationType.FLAT, DateUtils.getLocalDateOfTenant(),
|
||||
ChargePaymentMode.REGULAR, 1, new BigDecimal(100));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user