diff --git a/fineract-e2e-tests-core/src/test/resources/fineract-test-application.properties b/fineract-e2e-tests-core/src/test/resources/fineract-test-application.properties index eb5ef6e178d..961cf1c3657 100644 --- a/fineract-e2e-tests-core/src/test/resources/fineract-test-application.properties +++ b/fineract-e2e-tests-core/src/test/resources/fineract-test-application.properties @@ -37,7 +37,7 @@ fineract-test.messaging.jms.broker-password=${ACTIVEMQ_BROKER_PASSWORD:} fineract-test.messaging.jms.topic-name=${ACTIVEMQ_TOPIC_NAME:} fineract-test.event.verification-enabled=${EVENT_VERIFICATION_ENABLED:false} -fineract-test.event.wait-timeout-in-ms=${POLLING_EVENT_WAIT_TIMEOUT_IN_MS:5000} +fineract-test.event.wait-timeout-in-ms=${POLLING_EVENT_WAIT_TIMEOUT_IN_MS:15000} fineract-test.event.delay-in-ms=${POLLING_EVENT_WAIT_TIMEOUT_IN_MS:100} fineract-test.event.interval-in-ms=${POLLING_EVENT_WAIT_TIMEOUT_IN_MS:100} diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml index dd9549ade47..35b255e874e 100644 --- a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml +++ b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml @@ -259,5 +259,6 @@ + diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0242_fix_group_summary_report_parameters.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0242_fix_group_summary_report_parameters.xml new file mode 100644 index 00000000000..e47ba8edbdb --- /dev/null +++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0242_fix_group_summary_report_parameters.xml @@ -0,0 +1,80 @@ + + + + + + + select count(1) from stretchy_report where id = 96 and report_name = 'GroupSummaryCounts' + select count(1) from stretchy_parameter where id = 1019 and parameter_variable = 'groupId' + select count(1) from stretchy_report_parameter where report_id = 96 and parameter_id = 1019 + + + + + + + + + report_id = 96 and parameter_id = 1019 and report_parameter_name = 'groupId' + + + + + + + select count(1) from stretchy_report where id = 97 and report_name = 'GroupSummaryAmounts' + select count(1) from stretchy_parameter where id = 1019 and parameter_variable = 'groupId' + select count(1) from stretchy_report_parameter where report_id = 97 and parameter_id = 1019 + + + + + + + + + report_id = 97 and parameter_id = 1019 and report_parameter_name = 'groupId' + + + + + + + select count(1) from stretchy_report where id = 117 and report_name = 'GroupSavingSummary' + select count(1) from stretchy_parameter where id = 1019 and parameter_variable = 'groupId' + select count(1) from stretchy_report_parameter where report_id = 117 and parameter_id = 1019 + + + + + + + + + report_id = 117 and parameter_id = 1019 and report_parameter_name = 'groupId' + + + + + diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/GroupSummaryReportsIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/GroupSummaryReportsIntegrationTest.java new file mode 100644 index 00000000000..15ba3e97503 --- /dev/null +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/GroupSummaryReportsIntegrationTest.java @@ -0,0 +1,67 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.integrationtests; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import io.restassured.builder.RequestSpecBuilder; +import io.restassured.builder.ResponseSpecBuilder; +import io.restassured.http.ContentType; +import io.restassured.specification.RequestSpecification; +import io.restassured.specification.ResponseSpecification; +import java.util.Locale; +import org.apache.fineract.integrationtests.common.GroupHelper; +import org.apache.fineract.integrationtests.common.Utils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class GroupSummaryReportsIntegrationTest extends BaseLoanIntegrationTest { + + private RequestSpecification requestSpec; + private ResponseSpecification responseSpec; + + @BeforeEach + public void setup() { + Locale.setDefault(Locale.ENGLISH); + Utils.initializeRESTAssured(); + this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build(); + this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey()); + this.requestSpec.header("Fineract-Platform-TenantId", "default"); + this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build(); + } + + @Test + public void shouldRunGroupSummaryReportsWithNumericGroupIdParameter() { + final Integer groupId = GroupHelper.createGroup(this.requestSpec, this.responseSpec, true); + assertNotNull(groupId); + + assertGroupSummaryReportRuns("GroupSummaryCounts", groupId); + assertGroupSummaryReportRuns("GroupSummaryAmounts", groupId); + assertGroupSummaryReportRuns("GroupSavingSummary", groupId); + } + + private void assertGroupSummaryReportRuns(final String reportName, final Integer groupId) { + final String response = Utils.performServerGet(this.requestSpec, this.responseSpec, "/fineract-provider/api/v1/runreports/" + + reportName + "?R_groupId=" + groupId + "&genericResultSet=false&" + Utils.TENANT_IDENTIFIER, null); + + assertNotNull(response); + assertFalse(response.toLowerCase(Locale.ROOT).contains("operator does not exist")); + } +} diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/SavingsInterestPostingTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/SavingsInterestPostingTest.java index 284b31224c2..763c0d61a09 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/SavingsInterestPostingTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/SavingsInterestPostingTest.java @@ -19,6 +19,7 @@ package org.apache.fineract.integrationtests; import static org.apache.fineract.integrationtests.common.BusinessDateHelper.runAt; +import static org.awaitility.Awaitility.await; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; @@ -28,6 +29,7 @@ import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; +import java.time.Duration; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; @@ -66,6 +68,7 @@ public class SavingsInterestPostingTest { private static final Logger LOG = LoggerFactory.getLogger(SavingsInterestPostingTest.class); + private static final int DUPLICATE_PREVENTION_ACCOUNT_COUNT = 50; private static ResponseSpecification responseSpec; private static RequestSpecification requestSpec; private AccountHelper accountHelper; @@ -417,7 +420,7 @@ public void testPostInterestForDuplicatePrevention() { final String startDateString = DateTimeFormatter.ofPattern("dd MMMM yyyy", Locale.US).format(startDate); List accountIdList = new CopyOnWriteArrayList<>(); - ParallelExecutionHelper.runInParallel(IntStream.range(0, 200).boxed().toList(), (i) -> { + ParallelExecutionHelper.runInParallel(IntStream.range(0, DUPLICATE_PREVENTION_ACCOUNT_COUNT).boxed().toList(), (i) -> { final Integer clientId = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2025"); final Integer accountId = createTrackedSavingsAccount(clientId, productId, startDateString); @@ -426,14 +429,17 @@ public void testPostInterestForDuplicatePrevention() { savingsAccountHelper.depositToSavingsAccount(accountId, amount, startDateString, CommonConstants.RESPONSE_RESOURCE_ID); accountIdList.add(accountId); }); - Assertions.assertEquals(200, accountIdList.size(), "ERROR: Expected 200"); + Assertions.assertEquals(DUPLICATE_PREVENTION_ACCOUNT_COUNT, accountIdList.size(), + "ERROR: Expected " + DUPLICATE_PREVENTION_ACCOUNT_COUNT); schedulerJobHelper.executeAndAwaitJob(POST_INTEREST_JOB_NAME); schedulerJobHelper.executeAndAwaitJob(POST_INTEREST_JOB_NAME); - ParallelExecutionHelper.runInParallel(accountIdList, (accountId) -> { - List txs = getInterestTransactions(accountId); - Assertions.assertEquals(1, txs.size(), "ERROR: Duplicate interest postings exist."); + await().atMost(Duration.ofMinutes(2)).pollInterval(Duration.ofSeconds(2)).untilAsserted(() -> { + ParallelExecutionHelper.runInParallel(accountIdList, (accountId) -> { + List txs = getInterestTransactions(accountId); + Assertions.assertEquals(1, txs.size(), "ERROR: Duplicate interest postings exist for account " + accountId); + }); }); }); } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/FineractClientHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/FineractClientHelper.java index 6d2abb75f17..b01b684eb7a 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/FineractClientHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/FineractClientHelper.java @@ -18,6 +18,7 @@ */ package org.apache.fineract.integrationtests.common; +import java.time.Duration; import java.util.function.Consumer; import java.util.function.Function; import okhttp3.logging.HttpLoggingInterceptor; @@ -26,6 +27,8 @@ public final class FineractClientHelper { + private static final Duration READ_TIMEOUT = Duration.ofSeconds(180); + private static final FineractClient DEFAULT_FINERACT_CLIENT = createNewFineractClient(ConfigProperties.Backend.USERNAME, ConfigProperties.Backend.PASSWORD); @@ -43,7 +46,7 @@ public static FineractClient createNewFineractClient(String username, String pas String url = System.getProperty("fineract.it.url", buildURI()); // insecure(true) should *ONLY* ever be used for https://localhost:8443, NOT in real clients!! FineractClient.Builder builder = FineractClient.builder().insecure(true).baseURL(url).tenant(ConfigProperties.Backend.TENANT) - .basicAuth(username, password).logging(HttpLoggingInterceptor.Level.NONE); + .basicAuth(username, password).logging(HttpLoggingInterceptor.Level.NONE).readTimeout(READ_TIMEOUT); customizer.accept(builder); return builder.build(); } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/FineractFeignClientHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/FineractFeignClientHelper.java index d909989db0b..f8ee1910eb4 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/FineractFeignClientHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/FineractFeignClientHelper.java @@ -18,6 +18,7 @@ */ package org.apache.fineract.integrationtests.common; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Function; import org.apache.fineract.client.feign.FineractFeignClient; @@ -25,6 +26,8 @@ public final class FineractFeignClientHelper { + private static final int READ_TIMEOUT_SECONDS = 180; + private static final FineractFeignClient DEFAULT_FINERACT_FEIGN_CLIENT = createNewFineractFeignClient(ConfigProperties.Backend.USERNAME, ConfigProperties.Backend.PASSWORD); @@ -46,7 +49,7 @@ public static FineractFeignClient createNewFineractFeignClient(String username, Consumer customizer) { String url = System.getProperty("fineract.it.url", buildURI()); FineractFeignClient.Builder builder = FineractFeignClient.builder().baseUrl(url).credentials(username, password) - .disableSslVerification(true); + .disableSslVerification(true).readTimeout(READ_TIMEOUT_SECONDS, TimeUnit.SECONDS); customizer.accept(builder); return builder.build(); }