FINERACT-1724: Preparation for versioned APIs

This commit is contained in:
Arnold Galovics
2023-05-15 13:19:06 +02:00
committed by Arnold Gálovics
parent 190d995628
commit 037f7f264f
211 changed files with 1202 additions and 2215 deletions
@@ -0,0 +1,49 @@
/**
* 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;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.web.WebAppConfiguration;
@ExtendWith(SpringExtension.class)
@TestPropertySource("classpath:application-test.properties")
@WebAppConfiguration
@ContextConfiguration(classes = TestConfiguration.class)
public class AbstractSpringTest {
@BeforeAll
public static void cleanupBeforeClass() {
cleanupThreadLocals();
}
@BeforeEach
public void cleanupBeforeEach() {
cleanupThreadLocals();
}
private static void cleanupThreadLocals() {
ThreadLocalContextUtil.reset();
}
}
@@ -208,7 +208,7 @@ public class CommandStrategyProviderTest {
*/
@ParameterizedTest
@MethodSource("provideCommandStrategies")
public void testGetCommandStrategySuccess(final String url, final String httpMethod, final String beanName,
public void testGetCommandStrategySuccess_OldUrls(final String url, final String httpMethod, final String beanName,
final CommandStrategy commandStrategy) {
final ApplicationContext applicationContext = mock(ApplicationContext.class);
final CommandStrategyProvider commandStrategyProvider = new CommandStrategyProvider(applicationContext);
@@ -217,6 +217,31 @@ public class CommandStrategyProviderTest {
assertEquals(commandStrategy, result);
}
/**
* 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_VersionedUrls(final String url, final String httpMethod, final String beanName,
final CommandStrategy commandStrategy) {
String versionedUrl = "v1/" + url;
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(versionedUrl).method(httpMethod).build());
assertEquals(commandStrategy, result);
}
/**
* Command strategy provider for error scenarios.
*
@@ -0,0 +1,93 @@
/**
* 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.assertj.core.api.Assertions.assertThat;
import org.apache.fineract.batch.domain.BatchRequest;
import org.junit.jupiter.api.Test;
class CommandStrategyUtilsTest {
@Test
public void testRelativeUrlWithoutVersionRemovesV1() {
// given
BatchRequest request = new BatchRequest();
request.setRelativeUrl("v1/clients/123");
// when
String result = CommandStrategyUtils.relativeUrlWithoutVersion(request);
// then
assertThat(result).isEqualTo("clients/123");
}
@Test
public void testRelativeUrlWithoutVersionRemovesV2() {
// given
BatchRequest request = new BatchRequest();
request.setRelativeUrl("v2/clients/123");
// when
String result = CommandStrategyUtils.relativeUrlWithoutVersion(request);
// then
assertThat(result).isEqualTo("clients/123");
}
@Test
public void testRelativeUrlWithoutVersionRemovesV12() {
// given
BatchRequest request = new BatchRequest();
request.setRelativeUrl("v12/clients/123");
// when
String result = CommandStrategyUtils.relativeUrlWithoutVersion(request);
// then
assertThat(result).isEqualTo("clients/123");
}
@Test
public void testRelativeUrlWithoutVersionRemovesV1WhenQueryParamsPresent() {
// given
BatchRequest request = new BatchRequest();
request.setRelativeUrl("v1/clients/123?command=action&something=else");
// when
String result = CommandStrategyUtils.relativeUrlWithoutVersion(request);
// then
assertThat(result).isEqualTo("clients/123?command=action&something=else");
}
@Test
public void testRelativeUrlWithoutVersionRemovesNothing() {
// given
BatchRequest request = new BatchRequest();
request.setRelativeUrl("clients/123");
// when
String result = CommandStrategyUtils.relativeUrlWithoutVersion(request);
// then
assertThat(result).isEqualTo("clients/123");
}
@Test
public void testRelativeUrlWithoutVersionRemovesNothingWhenQueryParamsPresent() {
// given
BatchRequest request = new BatchRequest();
request.setRelativeUrl("clients/123?command=action&something=else");
// when
String result = CommandStrategyUtils.relativeUrlWithoutVersion(request);
// then
assertThat(result).isEqualTo("clients/123?command=action&something=else");
}
}
@@ -75,7 +75,7 @@ public class CreateTransactionLoanCommandStrategyTest {
private BatchRequest getBatchRequest(final Long loanId, final String command) {
final BatchRequest br = new BatchRequest();
String relativeUrl = "loans/" + loanId + "/transactions?command=" + command;
String relativeUrl = "v1/loans/" + loanId + "/transactions?command=" + command;
br.setRequestId(Long.valueOf(RandomStringUtils.randomNumeric(5)));
br.setRelativeUrl(relativeUrl);
@@ -98,7 +98,7 @@ public class GetLoanByIdCommandStrategyTest {
private BatchRequest getBatchRequest(final Long loanId, final String associations, final String exclude, final String fields) {
final BatchRequest br = new BatchRequest();
String relativeUrl = "loans/" + loanId;
String relativeUrl = "v1/loans/" + loanId;
Set<String> queryParams = new HashSet<>();
if (associations != null) {
@@ -0,0 +1,97 @@
/**
* 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.core.config;
import java.util.Set;
import java.util.stream.Collectors;
import javax.ws.rs.Path;
import org.apache.fineract.AbstractSpringTest;
import org.assertj.core.api.SoftAssertions;
import org.glassfish.jersey.server.model.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ClassUtils;
public class ApiVerificationTest extends AbstractSpringTest {
@Autowired
private JerseyConfig jerseyConfig;
@Test
public void testAllApiClassesAreNamedAsApiResource() {
Set<Class<?>> registeredClasses = jerseyConfig.getClasses();
SoftAssertions assertions = new SoftAssertions();
registeredClasses.stream().filter(this::isApi).forEach(apiClass -> verifyApiNaming(apiClass, assertions));
assertions.assertAll();
}
private void verifyApiNaming(Class<?> apiClass, SoftAssertions assertions) {
String apiClassName = ClassUtils.getUserClass(apiClass).getName();
String msg = "API class '%s' should have the postfix 'ApiResource'".formatted(apiClassName);
assertions.assertThat(apiClassName).as(msg).endsWith("ApiResource");
}
@Test
public void testAllApisAreVersioned() {
Set<Class<?>> registeredClasses = jerseyConfig.getClasses();
SoftAssertions assertions = new SoftAssertions();
registeredClasses.stream().filter(this::isApi).forEach(apiClass -> verifyApiIsVersioned(apiClass, assertions));
assertions.assertAll();
}
private boolean isApi(Class<?> c) {
return getPathAnnotation(c) != null;
}
private Path getPathAnnotation(Class<?> c) {
return AnnotationUtils.findAnnotation(c, Path.class);
}
private void verifyApiIsVersioned(Class<?> apiClass, SoftAssertions assertions) {
Resource apiResource = Resource.from(apiClass);
String basePath = apiResource.getPath();
Set<String> paths = apiResource.getChildResources() //
.stream() //
.map(Resource::getPath) //
.map(cPath -> normalizePath(basePath, cPath)) //
.collect(Collectors.toSet()); //
paths.add(normalizePath(basePath, null));
paths.forEach(fullPath -> {
String msg = "%s has a non versioned API on path %s".formatted(apiClass, fullPath);
assertions.assertThat(fullPath).as(msg).matches("^/(v[1-9][0-9]*/).*$");
});
}
private String normalizePath(String prefix, String path) {
String basePath = prefix;
if (!basePath.startsWith("/")) {
basePath = "/" + basePath;
}
if (path == null) {
return basePath;
}
if (basePath.endsWith("/")) {
return path.startsWith("/") ? basePath + path.substring(1) : basePath + path;
}
return path.startsWith("/") ? basePath + path : basePath + "/" + path;
}
}
@@ -74,7 +74,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(true, true, true, true);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.GET.name());
given(request.getPathInfo()).willReturn("/loans");
given(request.getPathInfo()).willReturn("/v1/loans");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -87,7 +87,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(true, false, false, false);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.GET.name());
given(request.getPathInfo()).willReturn("/loans");
given(request.getPathInfo()).willReturn("/v1/loans");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -115,7 +115,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(true, false, false, false);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.POST.name());
given(request.getPathInfo()).willReturn("/loans");
given(request.getPathInfo()).willReturn("/v1/loans");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -129,7 +129,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(true, false, false, false);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.POST.name());
given(request.getPathInfo()).willReturn("/jobs/1");
given(request.getPathInfo()).willReturn("/v1/jobs/1");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -143,7 +143,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, true, false, false);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.GET.name());
given(request.getPathInfo()).willReturn("/loans");
given(request.getPathInfo()).willReturn("/v1/loans");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -156,7 +156,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, true, false, false);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.POST.name());
given(request.getPathInfo()).willReturn("/loans");
given(request.getPathInfo()).willReturn("/v1/loans");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -169,7 +169,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, true, false, false);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.PUT.name());
given(request.getPathInfo()).willReturn("/loans/1");
given(request.getPathInfo()).willReturn("/v1/loans/1");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -196,7 +196,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, true, false, false);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.POST.name());
given(request.getPathInfo()).willReturn("/jobs/1");
given(request.getPathInfo()).willReturn("/v1/jobs/1");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -210,7 +210,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, false, true, true);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.POST.name());
given(request.getPathInfo()).willReturn("/jobs/1");
given(request.getPathInfo()).willReturn("/v1/jobs/1");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -224,7 +224,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, false, true, true);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.GET.name());
given(request.getPathInfo()).willReturn("/jobs");
given(request.getPathInfo()).willReturn("/v1/jobs");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -251,7 +251,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(true, false, false, false);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.POST.name());
given(request.getPathInfo()).willReturn("/batches");
given(request.getPathInfo()).willReturn("/v1/batches");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -264,7 +264,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, true, false, false);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.POST.name());
given(request.getPathInfo()).willReturn("/batches");
given(request.getPathInfo()).willReturn("/v1/batches");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -277,7 +277,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, false, true, true);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.POST.name());
given(request.getPathInfo()).willReturn("/batches");
given(request.getPathInfo()).willReturn("/v1/batches");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -290,7 +290,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, false, false, true);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.POST.name());
given(request.getPathInfo()).willReturn("/loans/catch-up");
given(request.getPathInfo()).willReturn("/v1/loans/catch-up");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -304,7 +304,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, false, true, false);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.POST.name());
given(request.getPathInfo()).willReturn("/loans/catch-up");
given(request.getPathInfo()).willReturn("/v1/loans/catch-up");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -319,7 +319,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, false, false, true);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.POST.name());
given(request.getPathInfo()).willReturn("/loans/is-catch-up-running");
given(request.getPathInfo()).willReturn("/v1/loans/is-catch-up-running");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -333,7 +333,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, false, true, false);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.POST.name());
given(request.getPathInfo()).willReturn("/loans/is-catch-up-running");
given(request.getPathInfo()).willReturn("/v1/loans/is-catch-up-running");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -348,7 +348,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(true, false, false, true);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.GET.name());
given(request.getPathInfo()).willReturn("/loans/oldest-cob-closed");
given(request.getPathInfo()).willReturn("/v1/loans/oldest-cob-closed");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -362,7 +362,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(true, false, false, false);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.GET.name());
given(request.getPathInfo()).willReturn("/loans/oldest-cob-closed");
given(request.getPathInfo()).willReturn("/v1/loans/oldest-cob-closed");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -375,7 +375,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, false, false, true);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.POST.name());
given(request.getPathInfo()).willReturn("/scheduler?command=start");
given(request.getPathInfo()).willReturn("/v1/scheduler?command=start");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -388,7 +388,7 @@ class FineractInstanceModeApiFilterTest {
FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(true, true, true, false);
given(fineractProperties.getMode()).willReturn(modeProperties);
given(request.getMethod()).willReturn(HttpMethod.POST.name());
given(request.getPathInfo()).willReturn("/scheduler?command=start");
given(request.getPathInfo()).willReturn("/v1/scheduler?command=start");
// when
underTest.doFilterInternal(request, response, filterChain);
// then
@@ -92,33 +92,34 @@ class LoanCOBApiFilterTest {
@Test
void shouldLoanAndExternalMatchToo() {
String externalId = UUID.randomUUID().toString();
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/12").matches());
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/12?correct=parameter").matches());
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/12?correct=parameter").matches());
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/rescheduleloans/12").matches());
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/rescheduleloans/12?correct=parameter").matches());
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/rescheduleloans/12?correct=parameter").matches());
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/external-id/" + externalId).matches());
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/v1/loans/12").matches());
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/v1/loans/12?correct=parameter").matches());
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/v1/loans/12?correct=parameter").matches());
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/v1/rescheduleloans/12").matches());
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/v1/rescheduleloans/12?correct=parameter").matches());
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/v1/rescheduleloans/12?correct=parameter").matches());
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/v1/loans/external-id/" + externalId).matches());
Assertions.assertTrue(
LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/external-id/" + externalId + "?additional=parameter").matches());
Assertions.assertEquals("12", LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/12").replaceAll("$1"));
Assertions.assertEquals("12", LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/12?correct=parameter").replaceAll("$1"));
Assertions.assertEquals("12", LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/rescheduleloans/12").replaceAll("$1"));
Assertions.assertEquals("12", LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/rescheduleloans/12?correct=parameter").replaceAll("$1"));
LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/v1/loans/external-id/" + externalId + "?additional=parameter").matches());
Assertions.assertEquals("12", LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/v1/loans/12").replaceAll("$1"));
Assertions.assertEquals("12", LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/v1/loans/12?correct=parameter").replaceAll("$1"));
Assertions.assertEquals("12", LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/v1/rescheduleloans/12").replaceAll("$1"));
Assertions.assertEquals("12",
LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/v1/rescheduleloans/12?correct=parameter").replaceAll("$1"));
Assertions.assertEquals(externalId,
LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/external-id/" + externalId).replaceAll("$1"));
Assertions.assertEquals(externalId,
LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/external-id/" + externalId + "?additional=parameter").replaceAll("$1"));
LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/v1/loans/external-id/" + externalId).replaceAll("$1"));
Assertions.assertEquals(externalId, LoanCOBApiFilter.LOAN_PATH_PATTERN
.matcher("/v1/loans/external-id/" + externalId + "?additional=parameter").replaceAll("$1"));
}
@Test
void shouldGlimAccountMatch() {
Assertions.assertTrue(LoanCOBApiFilter.LOAN_GLIMACCOUNT_PATH_PATTERN.matcher("/loans/glimAccount/12").matches());
Assertions
.assertTrue(LoanCOBApiFilter.LOAN_GLIMACCOUNT_PATH_PATTERN.matcher("/loans/glimAccount/12?additional=parameter").matches());
Assertions.assertEquals("12", LoanCOBApiFilter.LOAN_GLIMACCOUNT_PATH_PATTERN.matcher("/loans/glimAccount/12").replaceAll("$1"));
Assertions.assertTrue(LoanCOBApiFilter.LOAN_GLIMACCOUNT_PATH_PATTERN.matcher("/v1/loans/glimAccount/12").matches());
Assertions.assertTrue(
LoanCOBApiFilter.LOAN_GLIMACCOUNT_PATH_PATTERN.matcher("/v1/loans/glimAccount/12?additional=parameter").matches());
Assertions.assertEquals("12", LoanCOBApiFilter.LOAN_GLIMACCOUNT_PATH_PATTERN.matcher("/v1/loans/glimAccount/12").replaceAll("$1"));
Assertions.assertEquals("12",
LoanCOBApiFilter.LOAN_GLIMACCOUNT_PATH_PATTERN.matcher("/loans/glimAccount/12?additional=parameter").replaceAll("$1"));
LoanCOBApiFilter.LOAN_GLIMACCOUNT_PATH_PATTERN.matcher("/v1/loans/glimAccount/12?additional=parameter").replaceAll("$1"));
}
@Test
@@ -127,7 +128,7 @@ class LoanCOBApiFilterTest {
MockHttpServletResponse response = mock(MockHttpServletResponse.class);
FilterChain filterChain = mock(FilterChain.class);
given(request.getPathInfo()).willReturn("/jobs/2/inline");
given(request.getPathInfo()).willReturn("/v1/jobs/2/inline");
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
testObj.doFilterInternal(request, response, filterChain);
@@ -147,7 +148,7 @@ class LoanCOBApiFilterTest {
businessDates.put(BusinessDateType.COB_DATE, businessDate.minusDays(1));
ThreadLocalContextUtil.setBusinessDates(businessDates);
given(request.getPathInfo()).willReturn("/loans/invalid2LoanId/charges");
given(request.getPathInfo()).willReturn("/v1/loans/invalid2LoanId/charges");
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
given(context.authenticatedUser()).willReturn(appUser);
given(fineractProperties.getQuery()).willReturn(fineractQueryProperties);
@@ -167,7 +168,7 @@ class LoanCOBApiFilterTest {
FilterChain filterChain = mock(FilterChain.class);
AppUser appUser = mock(AppUser.class);
given(request.getPathInfo()).willReturn("/jobs/2/inline");
given(request.getPathInfo()).willReturn("/v1/jobs/2/inline");
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
given(context.authenticatedUser()).willReturn(appUser);
given(appUser.isBypassUser()).willReturn(true);
@@ -189,7 +190,7 @@ class LoanCOBApiFilterTest {
businessDates.put(BusinessDateType.COB_DATE, businessDate.minusDays(1));
ThreadLocalContextUtil.setBusinessDates(businessDates);
given(request.getPathInfo()).willReturn("/loans/2/charges");
given(request.getPathInfo()).willReturn("/v1/loans/2/charges");
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(false);
given(loanAccountLockService.isLoanSoftLocked(2L)).willReturn(false);
@@ -217,7 +218,7 @@ class LoanCOBApiFilterTest {
businessDates.put(BusinessDateType.COB_DATE, businessDate.minusDays(1));
ThreadLocalContextUtil.setBusinessDates(businessDates);
String uuid = UUID.randomUUID().toString();
given(request.getPathInfo()).willReturn("/loans/external-id/" + uuid + "/charges");
given(request.getPathInfo()).willReturn("/v1/loans/external-id/" + uuid + "/charges");
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(false);
given(loanAccountLockService.isLoanSoftLocked(2L)).willReturn(false);
@@ -246,7 +247,7 @@ class LoanCOBApiFilterTest {
businessDates.put(BusinessDateType.COB_DATE, businessDate.minusDays(1));
ThreadLocalContextUtil.setBusinessDates(businessDates);
Long resourceId = 123L;
given(request.getPathInfo()).willReturn("/rescheduleloans/" + resourceId + "/charges");
given(request.getPathInfo()).willReturn("/v1/rescheduleloans/" + resourceId + "/charges");
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(false);
given(loanAccountLockService.isLoanSoftLocked(2L)).willReturn(false);
@@ -271,7 +272,7 @@ class LoanCOBApiFilterTest {
FilterChain filterChain = mock(FilterChain.class);
AppUser appUser = mock(AppUser.class);
given(request.getPathInfo()).willReturn("/loans/2/charges");
given(request.getPathInfo()).willReturn("/v1/loans/2/charges");
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(false);
given(loanAccountLockService.isLoanSoftLocked(2L)).willReturn(true);
@@ -298,7 +299,7 @@ class LoanCOBApiFilterTest {
LoanIdAndLastClosedBusinessDate result = mock(LoanIdAndLastClosedBusinessDate.class);
given(result.getId()).willReturn(2L);
given(request.getPathInfo()).willReturn("/loans/2?command=approve");
given(request.getPathInfo()).willReturn("/v1/loans/2?command=approve");
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(false);
given(loanAccountLockService.isLoanSoftLocked(2L)).willReturn(true);
@@ -331,7 +332,7 @@ class LoanCOBApiFilterTest {
LoanIdAndLastClosedBusinessDate result = mock(LoanIdAndLastClosedBusinessDate.class);
given(result.getId()).willReturn(2L);
given(request.getPathInfo()).willReturn("/loans/2?command=approve");
given(request.getPathInfo()).willReturn("/v1/loans/2?command=approve");
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(false);
given(loanAccountLockService.isLoanSoftLocked(2L)).willReturn(false);
@@ -355,7 +356,7 @@ class LoanCOBApiFilterTest {
FilterChain filterChain = mock(FilterChain.class);
AppUser appUser = mock(AppUser.class);
given(request.getPathInfo()).willReturn("/loans");
given(request.getPathInfo()).willReturn("/v1/loans");
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
given(context.authenticatedUser()).willReturn(appUser);
@@ -372,7 +373,7 @@ class LoanCOBApiFilterTest {
FilterChain filterChain = mock(FilterChain.class);
AppUser appUser = mock(AppUser.class);
given(request.getPathInfo()).willReturn("/loans/catch-up");
given(request.getPathInfo()).willReturn("/v1/loans/catch-up");
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
given(context.authenticatedUser()).willReturn(appUser);
@@ -390,7 +391,7 @@ class LoanCOBApiFilterTest {
PrintWriter writer = mock(PrintWriter.class);
AppUser appUser = mock(AppUser.class);
given(request.getPathInfo()).willReturn("/loans/2/charges");
given(request.getPathInfo()).willReturn("/v1/loans/2/charges");
given(request.getMethod()).willReturn(HTTPMethods.POST.value());
given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(true);
given(response.getWriter()).willReturn(writer);
@@ -411,7 +412,7 @@ class LoanCOBApiFilterTest {
Long loanId = 2L;
AppUser appUser = mock(AppUser.class);
given(request.getPathInfo()).willReturn("/loans/glimAccount/2");
given(request.getPathInfo()).willReturn("/v1/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));