[FINERACT-1678] Reject write API calls for hard-locked loan accounts
This commit is contained in:
committed by
Arnold Gálovics
parent
e76adfbe56
commit
7be193dd0b
+2
@@ -24,4 +24,6 @@ import org.apache.fineract.cob.domain.LoanAccountLock;
|
|||||||
public interface LoanAccountLockService {
|
public interface LoanAccountLockService {
|
||||||
|
|
||||||
List<LoanAccountLock> getLockedLoanAccountByPage(int page, int limit);
|
List<LoanAccountLock> getLockedLoanAccountByPage(int page, int limit);
|
||||||
|
|
||||||
|
boolean isLoanHardLocked(Long loanId);
|
||||||
}
|
}
|
||||||
|
|||||||
+12
@@ -19,9 +19,12 @@
|
|||||||
package org.apache.fineract.cob.service;
|
package org.apache.fineract.cob.service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.fineract.cob.domain.LoanAccountLock;
|
import org.apache.fineract.cob.domain.LoanAccountLock;
|
||||||
import org.apache.fineract.cob.domain.LoanAccountLockRepository;
|
import org.apache.fineract.cob.domain.LoanAccountLockRepository;
|
||||||
|
import org.apache.fineract.cob.domain.LockOwner;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
@@ -39,4 +42,13 @@ public class LoanAccountLockServiceImpl implements LoanAccountLockService {
|
|||||||
Page<LoanAccountLock> loanAccountLocks = loanAccountLockRepository.findAll(loanAccountLockPage);
|
Page<LoanAccountLock> loanAccountLocks = loanAccountLockRepository.findAll(loanAccountLockPage);
|
||||||
return loanAccountLocks.getContent();
|
return loanAccountLocks.getContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLoanHardLocked(Long loanId) {
|
||||||
|
Optional<LoanAccountLock> loanAccountLockOptional = loanAccountLockRepository.findById(loanId);
|
||||||
|
return loanAccountLockOptional //
|
||||||
|
.filter(loanAccountLock -> LockOwner.LOAN_COB_CHUNK_PROCESSING.equals(loanAccountLock.getLockOwner()) //
|
||||||
|
|| LockOwner.LOAN_INLINE_COB_PROCESSING.equals(loanAccountLock.getLockOwner())) //
|
||||||
|
.filter(loanAccountLock -> StringUtils.isBlank(loanAccountLock.getError())).isPresent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -20,6 +20,7 @@
|
|||||||
package org.apache.fineract.infrastructure.core.config;
|
package org.apache.fineract.infrastructure.core.config;
|
||||||
|
|
||||||
import org.apache.fineract.infrastructure.instancemode.filter.FineractInstanceModeApiFilter;
|
import org.apache.fineract.infrastructure.instancemode.filter.FineractInstanceModeApiFilter;
|
||||||
|
import org.apache.fineract.infrastructure.jobs.filter.LoanCOBApiFilter;
|
||||||
import org.apache.fineract.infrastructure.security.filter.TenantAwareBasicAuthenticationFilter;
|
import org.apache.fineract.infrastructure.security.filter.TenantAwareBasicAuthenticationFilter;
|
||||||
import org.apache.fineract.infrastructure.security.filter.TwoFactorAuthenticationFilter;
|
import org.apache.fineract.infrastructure.security.filter.TwoFactorAuthenticationFilter;
|
||||||
import org.apache.fineract.infrastructure.security.service.TenantAwareJpaPlatformUserDetailsService;
|
import org.apache.fineract.infrastructure.security.service.TenantAwareJpaPlatformUserDetailsService;
|
||||||
@@ -56,6 +57,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private FineractInstanceModeApiFilter fineractInstanceModeApiFilter;
|
private FineractInstanceModeApiFilter fineractInstanceModeApiFilter;
|
||||||
|
@Autowired
|
||||||
|
private LoanCOBApiFilter loanCOBApiFilter;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private FineractProperties fineractProperties;
|
private FineractProperties fineractProperties;
|
||||||
@@ -86,6 +89,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
.and() //
|
.and() //
|
||||||
.addFilterAfter(fineractInstanceModeApiFilter, SecurityContextPersistenceFilter.class) //
|
.addFilterAfter(fineractInstanceModeApiFilter, SecurityContextPersistenceFilter.class) //
|
||||||
.addFilterAfter(tenantAwareBasicAuthenticationFilter(), FineractInstanceModeApiFilter.class) //
|
.addFilterAfter(tenantAwareBasicAuthenticationFilter(), FineractInstanceModeApiFilter.class) //
|
||||||
|
.addFilterAfter(loanCOBApiFilter, TenantAwareBasicAuthenticationFilter.class) //
|
||||||
.addFilterAfter(twoFactorAuthenticationFilter, BasicAuthenticationFilter.class); //
|
.addFilterAfter(twoFactorAuthenticationFilter, BasicAuthenticationFilter.class); //
|
||||||
|
|
||||||
if (serverProperties.getSsl().isEnabled()) {
|
if (serverProperties.getSsl().isEnabled()) {
|
||||||
|
|||||||
+10
@@ -89,6 +89,16 @@ public class ApiGlobalErrorResponse {
|
|||||||
return globalErrorResponse;
|
return globalErrorResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ApiGlobalErrorResponse loanIsLocked(final Long loanId) {
|
||||||
|
final ApiGlobalErrorResponse globalErrorResponse = new ApiGlobalErrorResponse();
|
||||||
|
globalErrorResponse.setHttpStatusCode(Status.CONFLICT.toString());
|
||||||
|
globalErrorResponse.setDeveloperMessage("Loan is locked by the COB job. Loan ID: " + loanId);
|
||||||
|
globalErrorResponse.setUserMessageGlobalisationCode("error.msg.loan.locked");
|
||||||
|
globalErrorResponse.setDefaultUserMessage("Loan is locked by the COB job. Loan ID: \" + loanId");
|
||||||
|
|
||||||
|
return globalErrorResponse;
|
||||||
|
}
|
||||||
|
|
||||||
public static ApiGlobalErrorResponse unAuthorized(final String defaultUserMessage) {
|
public static ApiGlobalErrorResponse unAuthorized(final String defaultUserMessage) {
|
||||||
final ApiGlobalErrorResponse globalErrorResponse = new ApiGlobalErrorResponse();
|
final ApiGlobalErrorResponse globalErrorResponse = new ApiGlobalErrorResponse();
|
||||||
globalErrorResponse.setHttpStatusCode("403");
|
globalErrorResponse.setHttpStatusCode("403");
|
||||||
|
|||||||
+133
@@ -0,0 +1,133 @@
|
|||||||
|
/**
|
||||||
|
* 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.infrastructure.jobs.filter;
|
||||||
|
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
|
import com.sun.research.ws.wadl.HTTPMethods;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.fineract.cob.service.LoanAccountLockService;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.GLIMAccountInfoRepository;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.GroupLoanIndividualMonitoringAccount;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||||
|
import org.apache.http.HttpStatus;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class LoanCOBApiFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
private final GLIMAccountInfoRepository glimAccountInfoRepository;
|
||||||
|
private final LoanAccountLockService loanAccountLockService;
|
||||||
|
|
||||||
|
private static final List<HTTPMethods> HTTP_METHODS = List.of(HTTPMethods.POST, HTTPMethods.PUT, HTTPMethods.DELETE);
|
||||||
|
private static final Function<String, Boolean> URL_FUNCTION = s -> s.matches("/loans/\\d+.*") || s.matches("/loans/glimAccount/\\d+.*");
|
||||||
|
private static final Integer LOAN_ID_INDEX_IN_URL = 2;
|
||||||
|
private static final Integer GLIM_ID_INDEX_IN_URL = 3;
|
||||||
|
private static final Integer GLIM_STRING_INDEX_IN_URL = 2;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
if (!isOnApiList(request)) {
|
||||||
|
proceed(filterChain, request, response);
|
||||||
|
} else {
|
||||||
|
Iterable<String> split = Splitter.on('/').split(request.getPathInfo());
|
||||||
|
Supplier<Stream<String>> streamSupplier = () -> StreamSupport.stream(split.spliterator(), false);
|
||||||
|
boolean isGlim = isGlim(streamSupplier);
|
||||||
|
Long loanId = getLoanId(isGlim, streamSupplier);
|
||||||
|
if (isLoanLocked(loanId, isGlim)) {
|
||||||
|
reject(loanId, response);
|
||||||
|
} else {
|
||||||
|
proceed(filterChain, request, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isLoanLocked(Long loanId, boolean isGlim) {
|
||||||
|
if (!isGlim) {
|
||||||
|
return loanAccountLockService.isLoanHardLocked(loanId);
|
||||||
|
} else {
|
||||||
|
GroupLoanIndividualMonitoringAccount glimAccount = glimAccountInfoRepository.findOneByIsAcceptingChildAndApplicationId(true,
|
||||||
|
BigDecimal.valueOf(loanId));
|
||||||
|
if (glimAccount != null) {
|
||||||
|
Set<Loan> loans = glimAccount.getChildLoan();
|
||||||
|
List<Long> loanIds = loans.stream().map(Loan::getId).toList();
|
||||||
|
return loanIds.stream().anyMatch(loanAccountLockService::isLoanHardLocked);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void proceed(FilterChain filterChain, HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws IOException, ServletException {
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reject(Long loanId, HttpServletResponse response) throws IOException {
|
||||||
|
response.setStatus(HttpStatus.SC_CONFLICT);
|
||||||
|
ApiGlobalErrorResponse errorResponse = ApiGlobalErrorResponse.loanIsLocked(loanId);
|
||||||
|
response.getWriter().write(errorResponse.toJson());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long getLoanId(boolean isGlim, Supplier<Stream<String>> streamSupplier) {
|
||||||
|
if (!isGlim) {
|
||||||
|
if (streamSupplier.get().count() >= LOAN_ID_INDEX_IN_URL + 1) {
|
||||||
|
return Long.valueOf(streamSupplier.get().skip(LOAN_ID_INDEX_IN_URL).findFirst().get());
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (streamSupplier.get().count() >= GLIM_ID_INDEX_IN_URL + 1) {
|
||||||
|
return Long.valueOf(streamSupplier.get().skip(GLIM_ID_INDEX_IN_URL).findFirst().get());
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isOnApiList(HttpServletRequest request) {
|
||||||
|
if (StringUtils.isBlank(request.getPathInfo())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return HTTP_METHODS.contains(HTTPMethods.fromValue(request.getMethod())) && URL_FUNCTION.apply(request.getPathInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isGlim(Supplier<Stream<String>> streamSupplier) {
|
||||||
|
if (streamSupplier.get().count() >= GLIM_STRING_INDEX_IN_URL + 1) {
|
||||||
|
return "glimAccount".equals(streamSupplier.get().skip(GLIM_STRING_INDEX_IN_URL).findFirst().get());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
+21
-8
@@ -39,6 +39,9 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService;
|
import org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService;
|
||||||
|
import org.apache.fineract.cob.domain.LoanAccountLockRepository;
|
||||||
|
import org.apache.fineract.cob.exceptions.LoanAccountLockCannotBeOverruledException;
|
||||||
|
import org.apache.fineract.cob.service.LoanAccountLockService;
|
||||||
import org.apache.fineract.infrastructure.codes.domain.CodeValue;
|
import org.apache.fineract.infrastructure.codes.domain.CodeValue;
|
||||||
import org.apache.fineract.infrastructure.codes.domain.CodeValueRepositoryWrapper;
|
import org.apache.fineract.infrastructure.codes.domain.CodeValueRepositoryWrapper;
|
||||||
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||||
@@ -278,6 +281,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
private final PostDatedChecksRepository postDatedChecksRepository;
|
private final PostDatedChecksRepository postDatedChecksRepository;
|
||||||
private final LoanDisbursementDetailsRepository loanDisbursementDetailsRepository;
|
private final LoanDisbursementDetailsRepository loanDisbursementDetailsRepository;
|
||||||
private final LoanRepaymentScheduleInstallmentRepository loanRepaymentScheduleInstallmentRepository;
|
private final LoanRepaymentScheduleInstallmentRepository loanRepaymentScheduleInstallmentRepository;
|
||||||
|
private final LoanAccountLockRepository loanAccountLockRepository;
|
||||||
|
private final LoanAccountLockService loanAccountLockService;
|
||||||
|
|
||||||
private static boolean isPartOfThisInstallment(LoanCharge loanCharge, LoanRepaymentScheduleInstallment e) {
|
private static boolean isPartOfThisInstallment(LoanCharge loanCharge, LoanRepaymentScheduleInstallment e) {
|
||||||
return e.getFromDate().isBefore(loanCharge.getDueDate()) && !loanCharge.getDueDate().isAfter(e.getDueDate());
|
return e.getFromDate().isBefore(loanCharge.getDueDate()) && !loanCharge.getDueDate().isAfter(e.getDueDate());
|
||||||
@@ -2551,20 +2556,28 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
|
|
||||||
final Staff fromLoanOfficer = this.loanAssembler.findLoanOfficerByIdIfProvided(fromLoanOfficerId);
|
final Staff fromLoanOfficer = this.loanAssembler.findLoanOfficerByIdIfProvided(fromLoanOfficerId);
|
||||||
final Staff toLoanOfficer = this.loanAssembler.findLoanOfficerByIdIfProvided(toLoanOfficerId);
|
final Staff toLoanOfficer = this.loanAssembler.findLoanOfficerByIdIfProvided(toLoanOfficerId);
|
||||||
|
List<Long> lockedLoanIds = new ArrayList<>();
|
||||||
|
|
||||||
for (final String loanIdString : loanIds) {
|
for (final String loanIdString : loanIds) {
|
||||||
final Long loanId = Long.valueOf(loanIdString);
|
final Long loanId = Long.valueOf(loanIdString);
|
||||||
final Loan loan = this.loanAssembler.assembleFrom(loanId);
|
final Loan loan = this.loanAssembler.assembleFrom(loanId);
|
||||||
businessEventNotifierService.notifyPreBusinessEvent(new LoanReassignOfficerBusinessEvent(loan));
|
if (loanAccountLockService.isLoanHardLocked(loanId)) {
|
||||||
checkClientOrGroupActive(loan);
|
lockedLoanIds.add(loanId);
|
||||||
|
} else {
|
||||||
|
businessEventNotifierService.notifyPreBusinessEvent(new LoanReassignOfficerBusinessEvent(loan));
|
||||||
|
checkClientOrGroupActive(loan);
|
||||||
|
|
||||||
if (!loan.hasLoanOfficer(fromLoanOfficer)) {
|
if (!loan.hasLoanOfficer(fromLoanOfficer)) {
|
||||||
throw new LoanOfficerAssignmentException(loanId, fromLoanOfficerId);
|
throw new LoanOfficerAssignmentException(loanId, fromLoanOfficerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
loan.reassignLoanOfficer(toLoanOfficer, dateOfLoanOfficerAssignment);
|
||||||
|
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||||
|
businessEventNotifierService.notifyPostBusinessEvent(new LoanReassignOfficerBusinessEvent(loan));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
loan.reassignLoanOfficer(toLoanOfficer, dateOfLoanOfficerAssignment);
|
if (!lockedLoanIds.isEmpty()) {
|
||||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
throw new LoanAccountLockCannotBeOverruledException("There are hard-lcoked loan accounts: " + lockedLoanIds);
|
||||||
businessEventNotifierService.notifyPostBusinessEvent(new LoanReassignOfficerBusinessEvent(loan));
|
|
||||||
}
|
}
|
||||||
this.loanRepositoryWrapper.flush();
|
this.loanRepositoryWrapper.flush();
|
||||||
|
|
||||||
|
|||||||
+135
@@ -0,0 +1,135 @@
|
|||||||
|
/**
|
||||||
|
* 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.infrastructure.jobs.filter;
|
||||||
|
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
import com.sun.research.ws.wadl.HTTPMethods;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Collections;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import org.apache.fineract.cob.service.LoanAccountLockService;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.GLIMAccountInfoRepository;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.GroupLoanIndividualMonitoringAccount;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||||
|
import org.apache.http.HttpStatus;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.mockito.junit.jupiter.MockitoSettings;
|
||||||
|
import org.mockito.quality.Strictness;
|
||||||
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||||
|
class LoanCOBApiFilterTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private LoanCOBApiFilter testObj;
|
||||||
|
@Mock
|
||||||
|
private LoanAccountLockService loanAccountLockService;
|
||||||
|
@Mock
|
||||||
|
private GLIMAccountInfoRepository glimAccountInfoRepository;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldProceedWhenUrlDoesNotMatch() throws ServletException, IOException {
|
||||||
|
MockHttpServletRequest request = mock(MockHttpServletRequest.class);
|
||||||
|
given(request.getPathInfo()).willReturn("/jobs/2/inline");
|
||||||
|
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
|
||||||
|
MockHttpServletResponse response = mock(MockHttpServletResponse.class);
|
||||||
|
FilterChain filterChain = mock(FilterChain.class);
|
||||||
|
testObj.doFilterInternal(request, response, filterChain);
|
||||||
|
verify(filterChain, times(1)).doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldProceedWhenLoanIsNotLocked() throws ServletException, IOException {
|
||||||
|
MockHttpServletRequest request = mock(MockHttpServletRequest.class);
|
||||||
|
MockHttpServletResponse response = mock(MockHttpServletResponse.class);
|
||||||
|
FilterChain filterChain = mock(FilterChain.class);
|
||||||
|
|
||||||
|
given(request.getPathInfo()).willReturn("/loans/2/charges");
|
||||||
|
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
|
||||||
|
given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(false);
|
||||||
|
|
||||||
|
testObj.doFilterInternal(request, response, filterChain);
|
||||||
|
verify(filterChain, times(1)).doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldProceedWhenLoanIsSoftLocked() throws ServletException, IOException {
|
||||||
|
MockHttpServletRequest request = mock(MockHttpServletRequest.class);
|
||||||
|
MockHttpServletResponse response = mock(MockHttpServletResponse.class);
|
||||||
|
FilterChain filterChain = mock(FilterChain.class);
|
||||||
|
|
||||||
|
given(request.getPathInfo()).willReturn("/loans/2/charges");
|
||||||
|
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
|
||||||
|
given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(false);
|
||||||
|
|
||||||
|
testObj.doFilterInternal(request, response, filterChain);
|
||||||
|
verify(filterChain, times(1)).doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldRejectWhenLoanIsHardLocked() throws ServletException, IOException {
|
||||||
|
MockHttpServletRequest request = mock(MockHttpServletRequest.class);
|
||||||
|
MockHttpServletResponse response = mock(MockHttpServletResponse.class);
|
||||||
|
FilterChain filterChain = mock(FilterChain.class);
|
||||||
|
PrintWriter writer = mock(PrintWriter.class);
|
||||||
|
|
||||||
|
given(request.getPathInfo()).willReturn("/loans/2/charges");
|
||||||
|
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
|
||||||
|
given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(true);
|
||||||
|
given(response.getWriter()).willReturn(writer);
|
||||||
|
|
||||||
|
testObj.doFilterInternal(request, response, filterChain);
|
||||||
|
verify(response, times(1)).setStatus(HttpStatus.SC_CONFLICT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldRejectWhenGlimLoanIsHardLocked() throws ServletException, IOException {
|
||||||
|
MockHttpServletRequest request = mock(MockHttpServletRequest.class);
|
||||||
|
MockHttpServletResponse response = mock(MockHttpServletResponse.class);
|
||||||
|
FilterChain filterChain = mock(FilterChain.class);
|
||||||
|
PrintWriter writer = mock(PrintWriter.class);
|
||||||
|
GroupLoanIndividualMonitoringAccount glimAccount = mock(GroupLoanIndividualMonitoringAccount.class);
|
||||||
|
Loan loan = mock(Loan.class);
|
||||||
|
Long loanId = 2L;
|
||||||
|
|
||||||
|
given(request.getPathInfo()).willReturn("/loans/glimAccount/2");
|
||||||
|
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
|
||||||
|
given(glimAccountInfoRepository.findOneByIsAcceptingChildAndApplicationId(true, BigDecimal.valueOf(2))).willReturn(glimAccount);
|
||||||
|
given(glimAccount.getChildLoan()).willReturn(Collections.singleton(loan));
|
||||||
|
given(loan.getId()).willReturn(loanId);
|
||||||
|
given(loanAccountLockService.isLoanHardLocked(loanId)).willReturn(true);
|
||||||
|
given(response.getWriter()).willReturn(writer);
|
||||||
|
|
||||||
|
testObj.doFilterInternal(request, response, filterChain);
|
||||||
|
verify(response, times(1)).setStatus(HttpStatus.SC_CONFLICT);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user