Skip to content

Commit 3f89d1a

Browse files
committed
FINERACT-2116: Add validation integration tests for Credit Bureau Configuration APIs
Signed-off-by: DeathGun44 <krishnamewara841@gmail.com>
1 parent 6875645 commit 3f89d1a

File tree

3 files changed

+247
-0
lines changed

3 files changed

+247
-0
lines changed

fineract-client/src/main/java/org/apache/fineract/client/util/FineractClient.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import org.apache.fineract.client.services.ClientsAddressApi;
5959
import org.apache.fineract.client.services.CodeValuesApi;
6060
import org.apache.fineract.client.services.CodesApi;
61+
import org.apache.fineract.client.services.CreditBureauConfigurationApi;
6162
import org.apache.fineract.client.services.CurrencyApi;
6263
import org.apache.fineract.client.services.DataTablesApi;
6364
import org.apache.fineract.client.services.DefaultApi;
@@ -199,6 +200,7 @@ public final class FineractClient {
199200
public final CentersApi centers;
200201
public final ChargesApi charges;
201202
public final ClientApi clients;
203+
public final CreditBureauConfigurationApi creditBureauConfiguration;
202204

203205
public final ClientSearchV2Api clientSearchV2;
204206
public final ClientChargesApi clientCharges;
@@ -333,6 +335,7 @@ private FineractClient(OkHttpClient okHttpClient, Retrofit retrofit) {
333335
centers = retrofit.create(CentersApi.class);
334336
charges = retrofit.create(ChargesApi.class);
335337
clients = retrofit.create(ClientApi.class);
338+
creditBureauConfiguration = retrofit.create(CreditBureauConfigurationApi.class);
336339
clientSearchV2 = retrofit.create(ClientSearchV2Api.class);
337340
clientCharges = retrofit.create(ClientChargesApi.class);
338341
clientIdentifiers = retrofit.create(ClientIdentifierApi.class);
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.fineract.integrationtests;
20+
21+
import static org.junit.jupiter.api.Assertions.assertEquals;
22+
import static org.junit.jupiter.api.Assertions.assertNotNull;
23+
import static org.junit.jupiter.api.Assertions.assertThrows;
24+
import static org.junit.jupiter.api.Assertions.assertTrue;
25+
26+
import com.google.gson.Gson;
27+
import com.google.gson.JsonObject;
28+
import com.google.gson.JsonParser;
29+
import io.restassured.builder.RequestSpecBuilder;
30+
import io.restassured.builder.ResponseSpecBuilder;
31+
import io.restassured.http.ContentType;
32+
import io.restassured.specification.RequestSpecification;
33+
import io.restassured.specification.ResponseSpecification;
34+
import java.util.HashMap;
35+
import java.util.Map;
36+
import lombok.extern.slf4j.Slf4j;
37+
import org.apache.fineract.client.util.CallFailedRuntimeException;
38+
import org.apache.fineract.integrationtests.common.CreditBureauConfigurationHelper;
39+
import org.apache.fineract.integrationtests.common.Utils;
40+
import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
41+
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
42+
import org.junit.jupiter.api.BeforeEach;
43+
import org.junit.jupiter.api.Test;
44+
import org.junit.jupiter.params.ParameterizedTest;
45+
import org.junit.jupiter.params.provider.CsvSource;
46+
47+
@Slf4j
48+
public class CreditBureauConfigurationValidationTest {
49+
50+
// Prerequisites - ThitsaWorks credit bureau is seeded in DB with ID 1
51+
private static final Long VALID_CREDIT_BUREAU_ID = 1L;
52+
private Long validOrganisationCreditBureauId;
53+
private Long validLoanProductId;
54+
55+
@BeforeEach
56+
public void setup() {
57+
ensureOrganisationCreditBureauExists();
58+
this.validLoanProductId = createTestLoanProduct();
59+
}
60+
61+
@ParameterizedTest(name = "Create configuration missing {0} should return 400")
62+
@CsvSource({ "configkey, value, description", "value, configkey, description", "description, configkey, value" })
63+
void testCreateConfiguration_MissingMandatoryFields(String fieldToOmit, String field1, String field2) {
64+
final Map<String, Object> jsonMap = new HashMap<>();
65+
jsonMap.put(field1, "testValue1");
66+
jsonMap.put(field2, "testValue2");
67+
final String jsonBody = new Gson().toJson(jsonMap);
68+
69+
CallFailedRuntimeException ex = assertThrows(CallFailedRuntimeException.class,
70+
() -> CreditBureauConfigurationHelper.createCreditBureauConfigurationRaw(validOrganisationCreditBureauId, jsonBody));
71+
72+
assertEquals(400, ex.getResponse().code());
73+
assertValidationErrorInMessage(ex.getMessage(), fieldToOmit);
74+
}
75+
76+
@Test
77+
void testCreateConfiguration_BlankConfigKey_ShouldFail400() {
78+
final Map<String, Object> jsonMap = new HashMap<>();
79+
jsonMap.put("configkey", "");
80+
jsonMap.put("value", "testValue");
81+
jsonMap.put("description", "testDescription");
82+
final String jsonBody = new Gson().toJson(jsonMap);
83+
84+
CallFailedRuntimeException ex = assertThrows(CallFailedRuntimeException.class,
85+
() -> CreditBureauConfigurationHelper.createCreditBureauConfigurationRaw(validOrganisationCreditBureauId, jsonBody));
86+
87+
assertEquals(400, ex.getResponse().code());
88+
assertValidationErrorInMessage(ex.getMessage(), "configkey");
89+
}
90+
91+
@Test
92+
void testCreateConfiguration_ExceedingLength_ShouldFail400() {
93+
final String longValue = "a".repeat(101);
94+
final Map<String, Object> jsonMap = new HashMap<>();
95+
jsonMap.put("configkey", longValue);
96+
jsonMap.put("value", "testValue");
97+
jsonMap.put("description", "testDescription");
98+
final String jsonBody = new Gson().toJson(jsonMap);
99+
100+
CallFailedRuntimeException ex = assertThrows(CallFailedRuntimeException.class,
101+
() -> CreditBureauConfigurationHelper.createCreditBureauConfigurationRaw(validOrganisationCreditBureauId, jsonBody));
102+
103+
assertEquals(400, ex.getResponse().code());
104+
assertValidationErrorInMessage(ex.getMessage(), "configkey");
105+
}
106+
107+
@Test
108+
void testAddOrganisationCreditBureau_MissingAlias_ShouldFail400() {
109+
final Map<String, Object> jsonMap = new HashMap<>();
110+
jsonMap.put("isActive", true);
111+
final String jsonBody = new Gson().toJson(jsonMap);
112+
113+
CallFailedRuntimeException ex = assertThrows(CallFailedRuntimeException.class,
114+
() -> CreditBureauConfigurationHelper.addOrganisationCreditBureauRaw(VALID_CREDIT_BUREAU_ID, jsonBody));
115+
116+
assertEquals(400, ex.getResponse().code());
117+
assertValidationErrorInMessage(ex.getMessage(), "alias");
118+
}
119+
120+
@Test
121+
void testAddOrganisationCreditBureau_BlankAlias_ShouldFail400() {
122+
final Map<String, Object> jsonMap = new HashMap<>();
123+
jsonMap.put("alias", "");
124+
jsonMap.put("isActive", true);
125+
final String jsonBody = new Gson().toJson(jsonMap);
126+
127+
CallFailedRuntimeException ex = assertThrows(CallFailedRuntimeException.class,
128+
() -> CreditBureauConfigurationHelper.addOrganisationCreditBureauRaw(VALID_CREDIT_BUREAU_ID, jsonBody));
129+
130+
assertEquals(400, ex.getResponse().code());
131+
assertValidationErrorInMessage(ex.getMessage(), "alias");
132+
}
133+
134+
@Test
135+
void testAddOrganisationCreditBureau_ExceedingAliasLength_ShouldFail400() {
136+
final String longAlias = "a".repeat(101);
137+
final Map<String, Object> jsonMap = new HashMap<>();
138+
jsonMap.put("alias", longAlias);
139+
jsonMap.put("isActive", true);
140+
final String jsonBody = new Gson().toJson(jsonMap);
141+
142+
CallFailedRuntimeException ex = assertThrows(CallFailedRuntimeException.class,
143+
() -> CreditBureauConfigurationHelper.addOrganisationCreditBureauRaw(VALID_CREDIT_BUREAU_ID, jsonBody));
144+
145+
assertEquals(400, ex.getResponse().code());
146+
assertValidationErrorInMessage(ex.getMessage(), "alias");
147+
}
148+
149+
@ParameterizedTest(name = "Create mapping missing {0} should return 400")
150+
@CsvSource({ "isCreditcheckMandatory", "skipCreditcheckInFailure", "stalePeriod" })
151+
void testCreateMapping_MissingMandatoryFields(String fieldToOmit) {
152+
final Map<String, Object> jsonMap = buildMappingJsonOmitting(fieldToOmit);
153+
final String jsonBody = new Gson().toJson(jsonMap);
154+
155+
CallFailedRuntimeException ex = assertThrows(CallFailedRuntimeException.class,
156+
() -> CreditBureauConfigurationHelper.createLoanProductMappingRaw(validOrganisationCreditBureauId, jsonBody));
157+
158+
assertEquals(400, ex.getResponse().code());
159+
assertValidationErrorInMessage(ex.getMessage(), fieldToOmit);
160+
}
161+
162+
@Test
163+
void testCreateMapping_MissingLoanProductId_ShouldFail400() {
164+
final Map<String, Object> jsonMap = buildMappingJsonOmitting("loanProductId");
165+
final String jsonBody = new Gson().toJson(jsonMap);
166+
167+
CallFailedRuntimeException ex = assertThrows(CallFailedRuntimeException.class,
168+
() -> CreditBureauConfigurationHelper.createLoanProductMappingRaw(validOrganisationCreditBureauId, jsonBody));
169+
170+
assertEquals(400, ex.getResponse().code());
171+
assertValidationErrorInMessage(ex.getMessage(), "loanProductId");
172+
}
173+
174+
private void ensureOrganisationCreditBureauExists() {
175+
String response = CreditBureauConfigurationHelper.addOrganisationCreditBureau(VALID_CREDIT_BUREAU_ID,
176+
"Test Credit Bureau " + System.currentTimeMillis(), true);
177+
JsonObject json = JsonParser.parseString(response).getAsJsonObject();
178+
Integer resourceId = json.get("resourceId").getAsInt();
179+
assertNotNull(resourceId, "Organisation credit bureau creation should return resourceId");
180+
this.validOrganisationCreditBureauId = resourceId.longValue();
181+
log.info("Created organisation credit bureau with ID: {}", validOrganisationCreditBureauId);
182+
}
183+
184+
private Long createTestLoanProduct() {
185+
Utils.initializeRESTAssured();
186+
final RequestSpecification requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
187+
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
188+
final ResponseSpecification responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
189+
final LoanTransactionHelper loanTransactionHelper = new LoanTransactionHelper(requestSpec, responseSpec);
190+
final String loanProductJSON = new LoanProductTestBuilder().withPrincipal("1000").withRepaymentAfterEvery("1")
191+
.withRepaymentTypeAsMonth().withNumberOfRepayments("1").withInterestRateFrequencyTypeAsMonths()
192+
.withinterestRatePerPeriod("0").withInterestTypeAsDecliningBalance().withAmortizationTypeAsEqualInstallments().build(null);
193+
return (long) loanTransactionHelper.getLoanProductId(loanProductJSON);
194+
}
195+
196+
private Map<String, Object> buildMappingJsonOmitting(String fieldToOmit) {
197+
final Map<String, Object> jsonMap = new HashMap<>();
198+
if (!"loanProductId".equals(fieldToOmit)) {
199+
jsonMap.put("loanProductId", validLoanProductId);
200+
}
201+
if (!"isCreditcheckMandatory".equals(fieldToOmit)) {
202+
jsonMap.put("isCreditcheckMandatory", true);
203+
}
204+
if (!"skipCreditcheckInFailure".equals(fieldToOmit)) {
205+
jsonMap.put("skipCreditcheckInFailure", false);
206+
}
207+
if (!"stalePeriod".equals(fieldToOmit)) {
208+
jsonMap.put("stalePeriod", 30);
209+
}
210+
jsonMap.put("isActive", true);
211+
return jsonMap;
212+
}
213+
214+
private void assertValidationErrorInMessage(String message, String expectedFieldInError) {
215+
assertNotNull(message, "Exception message should not be null");
216+
assertTrue(message.contains(expectedFieldInError),
217+
String.format("Expected validation error for field '%s' in message: %s", expectedFieldInError, message));
218+
log.info("Received expected validation error for field '{}'", expectedFieldInError);
219+
}
220+
}

integration-tests/src/test/java/org/apache/fineract/integrationtests/common/CreditBureauConfigurationHelper.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import java.util.HashMap;
2828
import java.util.List;
2929
import java.util.Map;
30+
import org.apache.fineract.client.services.CreditBureauConfigurationApi;
31+
import org.apache.fineract.client.util.Calls;
3032
import org.slf4j.Logger;
3133
import org.slf4j.LoggerFactory;
3234

@@ -214,4 +216,26 @@ public static String updateCreditBureauConfigurationAsJson(final String configKe
214216
return new Gson().toJson(map);
215217
}
216218

219+
private static CreditBureauConfigurationApi api() {
220+
return FineractClientHelper.getFineractClient().creditBureauConfiguration;
221+
}
222+
223+
public static String addOrganisationCreditBureau(Long creditBureauId, String alias, boolean isActive) {
224+
final HashMap<String, Object> map = new HashMap<>();
225+
map.put("alias", alias);
226+
map.put("isActive", isActive);
227+
return Calls.ok(api().addOrganisationCreditBureau(creditBureauId, new Gson().toJson(map)));
228+
}
229+
230+
public static String createCreditBureauConfigurationRaw(Long creditBureauId, String jsonBody) {
231+
return Calls.ok(api().createCreditBureauConfiguration(creditBureauId, jsonBody));
232+
}
233+
234+
public static String addOrganisationCreditBureauRaw(Long creditBureauId, String jsonBody) {
235+
return Calls.ok(api().addOrganisationCreditBureau(creditBureauId, jsonBody));
236+
}
237+
238+
public static String createLoanProductMappingRaw(Long organisationCreditBureauId, String jsonBody) {
239+
return Calls.ok(api().createCreditBureauLoanProductMapping(organisationCreditBureauId, jsonBody));
240+
}
217241
}

0 commit comments

Comments
 (0)