From 6ba5d7d5c491db70a8069b6bc891fac897be09af Mon Sep 17 00:00:00 2001 From: Janos Haber Date: Fri, 11 Nov 2022 15:31:05 +0100 Subject: [PATCH] Fix credit bureau organisation result processing in the test case. FINERACT-1724 [x] Unit test for ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl [x] Integration test for CreditBureau with WireMock [x] Fix enum key case sensitivity on postgres [x] Fix update key typo [x] Add missing credit bureau organization fix for test cases --- .../domain/CreditBureauConfiguration.java | 2 +- ...auIntegrationWritePlatformServiceImpl.java | 11 +- ...tegrationWritePlatformServiceImplTest.java | 572 ++++++++++++++++++ integration-tests/dependencies.gradle | 1 + .../integrationtests/CreditBureauTest.java | 187 ++++++ .../CreditBureauConfigurationHelper.java | 80 ++- .../common/CreditBureauIntegrationHelper.java | 69 +++ 7 files changed, 910 insertions(+), 12 deletions(-) create mode 100644 fineract-provider/src/test/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImplTest.java create mode 100644 integration-tests/src/test/java/org/apache/fineract/integrationtests/CreditBureauTest.java create mode 100644 integration-tests/src/test/java/org/apache/fineract/integrationtests/common/CreditBureauIntegrationHelper.java diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauConfiguration.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauConfiguration.java index b00412b20..d7003cbe4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauConfiguration.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauConfiguration.java @@ -68,7 +68,7 @@ public class CreditBureauConfiguration extends AbstractPersistableCustom { final Map actualChanges = new LinkedHashMap<>(1); - final String configurationKey = "configurationKey"; + final String configurationKey = "configkey"; if (command.isChangeInStringParameterNamed(configurationKey, this.configurationKey)) { final String newValue = command.stringValueOfParameterNamed(configurationKey); diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java index 1e1fd69a6..fd97328c7 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java @@ -73,11 +73,21 @@ public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implemen private final CreditBureauConfigurationRepositoryWrapper configDataRepository; private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer; + private final OkHttpClient client; + @Autowired public ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl(final PlatformSecurityContext context, final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepositoryWrapper, final CreditBureauConfigurationRepositoryWrapper configDataRepository, final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) { + this(new OkHttpClient(), context, fromApiJsonHelper, tokenRepositoryWrapper, configDataRepository, fromApiJsonDeserializer); + } + + public ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl(final OkHttpClient okHttpClient, + final PlatformSecurityContext context, final FromJsonHelper fromApiJsonHelper, + final TokenRepositoryWrapper tokenRepositoryWrapper, final CreditBureauConfigurationRepositoryWrapper configDataRepository, + final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) { + this.client = okHttpClient; this.context = context; this.tokenRepositoryWrapper = tokenRepositoryWrapper; this.configDataRepository = configDataRepository; @@ -93,7 +103,6 @@ public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implemen String reponseMessage = null; RequestBody requestBody = null; - OkHttpClient client = new OkHttpClient(); if (process.equals("UploadCreditReport")) { String fileName = fileData.getFileName(); diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImplTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImplTest.java new file mode 100644 index 000000000..d241255ae --- /dev/null +++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImplTest.java @@ -0,0 +1,572 @@ +/** + * 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.creditbureau.service; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.gson.JsonParser; +import io.vavr.CheckedFunction1; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatterBuilder; +import java.util.List; +import java.util.function.Function; +import java.util.function.Supplier; +import okhttp3.Call; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; +import okio.BufferedSink; +import okio.Okio; +import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException; +import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper; +import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauConfigurations; +import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauReportData; +import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration; +import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper; +import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken; +import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper; +import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer; +import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; + +public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImplTest { + + @Spy + private FromJsonHelper fromJsonHelper = new FromJsonHelper(); + + @Spy + private CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer = new CreditBureauTokenCommandFromApiJsonDeserializer( + fromJsonHelper); + @Mock + private OkHttpClient okHttpClient; + + @Mock + private CreditBureauConfigurationRepositoryWrapper configurationRepositoryWrapper; + + @Mock + private PlatformSecurityContext platformSecurityContext; + + @Mock + private TokenRepositoryWrapper tokenRepositoryWrapper; + + private final ObjectMapper mapper = new ObjectMapper(); + + @InjectMocks + private ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl underTest; + + @BeforeEach + public void setup() { + MockitoAnnotations.openMocks(this); + when(configurationRepositoryWrapper.getCreditBureauConfigData(1, CreditBureauConfigurations.USERNAME.name())) + .thenReturn(new CreditBureauConfiguration().setValue("testUsername")); + when(configurationRepositoryWrapper.getCreditBureauConfigData(1, CreditBureauConfigurations.PASSWORD.name())) + .thenReturn(new CreditBureauConfiguration().setValue("testPassword")); + when(configurationRepositoryWrapper.getCreditBureauConfigData(1, CreditBureauConfigurations.CREDITREPORTURL.name())) + .thenReturn(new CreditBureauConfiguration().setValue("https://credit.report.url/api/")); + when(configurationRepositoryWrapper.getCreditBureauConfigData(1, CreditBureauConfigurations.SEARCHURL.name())) + .thenReturn(new CreditBureauConfiguration().setValue("https://search.report.url/api/")); + when(configurationRepositoryWrapper.getCreditBureauConfigData(1, CreditBureauConfigurations.TOKENURL.name())) + .thenReturn(new CreditBureauConfiguration().setValue("https://token.url/api/")); + when(configurationRepositoryWrapper.getCreditBureauConfigData(1, CreditBureauConfigurations.SUBSCRIPTIONID.name())) + .thenReturn(new CreditBureauConfiguration().setValue("subscriptionId")); + when(configurationRepositoryWrapper.getCreditBureauConfigData(1, CreditBureauConfigurations.SUBSCRIPTIONKEY.name())) + .thenReturn(new CreditBureauConfiguration().setValue("subscriptionKey")); + + } + + private String createResponseObjectArrayData(Supplier responseMessageGenerator, Function dataGenerator) + throws JsonProcessingException { + ObjectNode jsonResponse = mapper.createObjectNode(); + + jsonResponse.put("ResponseMessage", responseMessageGenerator.get()); + jsonResponse.set("Data", dataGenerator.apply(mapper.createArrayNode())); + return mapper.writeValueAsString(jsonResponse); + } + + private String createResponseObjectObjectData(Supplier responseMessageGenerator, Function dataGenerator) + throws JsonProcessingException { + ObjectNode jsonResponse = mapper.createObjectNode(); + + jsonResponse.put("ResponseMessage", responseMessageGenerator.get()); + jsonResponse.set("Data", dataGenerator.apply(mapper.createObjectNode())); + return mapper.writeValueAsString(jsonResponse); + } + + public void mockOkHttpCall(CheckedFunction1 responseGenerator) throws IOException { + ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(Request.class); + Call callMock = mock(Call.class); + when(okHttpClient.newCall(requestCaptor.capture())).thenReturn(callMock); + when(callMock.execute()).thenAnswer(invocation -> responseGenerator.apply(requestCaptor.getValue())); + } + + public Response createOkhttpResponse(Request request, String body) { + return new Response.Builder().request(request).protocol(okhttp3.Protocol.HTTP_1_1).code(200).message("") + .body(ResponseBody.create(body, MediaType.parse("application/json"))).build(); + } + + public Response createOkhttpResponse(Request request, int status, String message, ResponseBody body) { + return new Response.Builder().request(request).protocol(okhttp3.Protocol.HTTP_1_1).code(status).message(message).body(body).build(); + } + + public Response createOkhttpResponse(Request request, int status, String message) { + return new Response.Builder().request(request).protocol(okhttp3.Protocol.HTTP_1_1).code(status).message(message) + .body(ResponseBody.create(message, MediaType.parse("text/html"))).build(); + } + + @Test + public void okHttpInternalServerErrorTest() throws IOException { + + mockOkHttpCall(request -> createOkhttpResponse(request, 500, "Internal Server Error")); + + assertThrows(PlatformDataIntegrityException.class, () -> { + underTest.okHttpConnectionMethod("testUser", "testPassword", "subscriptionKey", "subscriptionId", "https://nrc.test.url.com", + "AccessToken", null, null, 0L, "nrcId", "NRC"); + + }); + + } + + @Test + public void okHttpIOExceptionTest() throws IOException { + mockOkHttpCall(request -> { + throw new IOException("IO Exception"); + }); + + assertThrows(PlatformDataIntegrityException.class, () -> { + underTest.okHttpConnectionMethod("testUser", "testPassword", "subscriptionKey", "subscriptionId", "https://nrc.test.url.com", + "AccessToken", null, null, 0L, "nrcId", "NRC"); + + }); + + } + + @Test + public void okHttpNrcSuccessTest() throws IOException { + + String jsonResponse = createResponseObjectArrayData(() -> "Success", + data -> data.add(mapper.createObjectNode().put("UniqueID", "123456"))); + + mockOkHttpCall(request -> { + assertEquals(request.header("Authorization"), "Bearer AccessToken"); + assertEquals(request.header("mcix-subscription-key"), "subscriptionKey"); + assertEquals(request.header("mcix-subscription-id"), "subscriptionId"); + assertEquals(request.header("Content-Type"), "application/x-www-form-urlencoded"); + BufferedSink sink = Okio.buffer(Okio.sink(new ByteArrayOutputStream())); + request.body().writeTo(sink); + String urlEncodedForm = sink.getBuffer().readUtf8(); + assertTrue(urlEncodedForm.contains("nrc=nrcId")); + return createOkhttpResponse(request, jsonResponse); + }); + + String result = underTest.okHttpConnectionMethod("testUser", "testPassword", "subscriptionKey", "subscriptionId", + "https://nrc.test.url.com", "AccessToken", null, null, 0L, "nrcId", "NRC"); + assertEquals(jsonResponse, result); + } + + @Test + public void okHttpNrcNoTokenTest() throws IOException { + + String jsonResponse = createResponseObjectArrayData(() -> "Success", + data -> data.add(mapper.createObjectNode().put("UniqueID", "123456"))); + + mockOkHttpCall(request -> { + List auhtorizationHeaders = request.headers("Authorization"); + assertTrue(auhtorizationHeaders.isEmpty()); + assertEquals(request.header("mcix-subscription-key"), "subscriptionKey"); + assertEquals(request.header("mcix-subscription-id"), "subscriptionId"); + assertEquals(request.header("Content-Type"), "application/x-www-form-urlencoded"); + BufferedSink sink = Okio.buffer(Okio.sink(new ByteArrayOutputStream())); + request.body().writeTo(sink); + String urlEncodedForm = sink.getBuffer().readUtf8(); + assertTrue(urlEncodedForm.contains("nrc=nrcId")); + return createOkhttpResponse(request, jsonResponse); + }); + + String result = underTest.okHttpConnectionMethod("testUser", "testPassword", "subscriptionKey", "subscriptionId", + "https://nrc.test.url.com", null, null, null, 0L, "nrcId", "NRC"); + assertEquals(jsonResponse, result); + } + + @Test + public void okhttpUploadCreditReportTest() throws IOException { + + String jsonResponse = createResponseObjectArrayData(() -> "UPLOADED", data -> data); + + Path temp = Files.createTempFile("upload_test" + System.currentTimeMillis(), ".data"); + Files.writeString(temp, "test"); + + mockOkHttpCall(request -> { + assertEquals(request.header("Authorization"), "Bearer AccessToken"); + assertEquals(request.header("mcix-subscription-key"), "subscriptionKey"); + assertEquals(request.header("mcix-subscription-id"), "subscriptionId"); + assertEquals(request.header("Content-Type"), "multipart/form-data"); + return createOkhttpResponse(request, jsonResponse); + }); + FormDataContentDisposition fileDetail = mock(FormDataContentDisposition.class); + when(fileDetail.getFileName()).thenReturn("test.pdf"); + + PlatformDataIntegrityException resultException = assertThrows(PlatformDataIntegrityException.class, () -> { + underTest.okHttpConnectionMethod("testUser", "testPassword", "subscriptionKey", "subscriptionId", "https://upload.test.url.com", + "AccessToken", temp.toFile(), fileDetail, 0L, "nrcId", "UploadCreditReport"); + }); + assertEquals("UPLOADED", resultException.getDefaultUserMessage()); + } + + @Test + public void okHttpNoTokenTest() throws IOException { + mockOkHttpCall(request -> { + List auhtorizationHeaders = request.headers("Authorization"); + assertTrue(auhtorizationHeaders.isEmpty()); + assertEquals(request.header("mcix-subscription-key"), "subscriptionKey"); + assertEquals(request.header("mcix-subscription-id"), "subscriptionId"); + assertEquals(request.header("Content-Type"), "application/x-www-form-urlencoded"); + BufferedSink sink = Okio.buffer(Okio.sink(new ByteArrayOutputStream())); + request.body().writeTo(sink); + String urlEncodedForm = sink.getBuffer().readUtf8(); + assertTrue(urlEncodedForm.contains("grant_type=password")); + assertTrue(urlEncodedForm.contains("userName=testUser")); + assertTrue(urlEncodedForm.contains("password=testPassword")); + return createOkhttpResponse(request, 401, "Unauthorized"); + }); + assertThrows(PlatformDataIntegrityException.class, () -> { + underTest.okHttpConnectionMethod("testUser", "testPassword", "subscriptionKey", "subscriptionId", "https://nrc.test.url.com", + null, null, null, 0L, "nrcId", "token"); + }); + } + + @Test + public void okHttpGetNrcReportSuccessTest() throws IOException { + + String jsonResponse = createResponseObjectArrayData(() -> "Success", + data -> data.add(mapper.createObjectNode().put("UniqueID", "123456"))); + + mockOkHttpCall(request -> { + assertEquals(request.header("Authorization"), "Bearer AccessToken"); + assertEquals(request.header("mcix-subscription-key"), "subscriptionKey"); + assertEquals(request.header("mcix-subscription-id"), "subscriptionId"); + assertEquals(request.header("Content-Type"), "application/x-www-form-urlencoded"); + return createOkhttpResponse(request, jsonResponse); + }); + + String result = underTest.okHttpConnectionMethod("testUser", "testPassword", "subscriptionKey", "subscriptionId", + "https://nrc.test.url.com", "AccessToken", null, null, 0L, "nrcId", "CreditReport"); + assertEquals(jsonResponse, result); + } + + @Test + public void okHttpForbiddenTest() throws IOException { + mockOkHttpCall(request -> createOkhttpResponse(request, 403, "Forbidden")); + + assertThrows(PlatformDataIntegrityException.class, () -> { + underTest.okHttpConnectionMethod("testUser", "testPassword", "subscriptionKey", "subscriptionId", "https://nrc.test.url.com", + "AccessToken", null, null, 0L, "nrcId", "CreditReport"); + }); + } + + @Test // TODO: Null body not handled + public void okHttpNoBodyReturned() throws IOException { + mockOkHttpCall(request -> createOkhttpResponse(request, 200, "OK", null)); + + assertThrows(NullPointerException.class, () -> { + underTest.okHttpConnectionMethod("testUser", "testPassword", "subscriptionKey", "subscriptionId", "https://nrc.test.url.com", + "AccessToken", null, null, 0L, "nrcId", "CreditReport"); + }); + } + + @Test + public void extractUniqueIdSuccessTest() throws JsonProcessingException { + String json = createResponseObjectArrayData(() -> "Success", data -> data.add(mapper.createObjectNode().put("UniqueID", "123456"))); + Long id = underTest.extractUniqueId(json); + assertEquals(123456L, id.longValue()); + } + + @Test + public void extractUniqueIdEmptyResultTest() throws JsonProcessingException { + String json = createResponseObjectArrayData(() -> "NoResult", data -> data); + PlatformDataIntegrityException result = assertThrows(PlatformDataIntegrityException.class, () -> { + underTest.extractUniqueId(json); + }); + assertEquals("NoResult", result.getDefaultUserMessage()); + } + + @Test + public void extractUniqueIdMultipleResultTest() throws JsonProcessingException { + String json = createResponseObjectArrayData(() -> "NoResult", + data -> data.add(mapper.createObjectNode().put("UniqueID", "123456").put("NRC", "NRCID1")) + .add(mapper.createObjectNode().put("UniqueID", "7654321").put("NRC", "NRCID2"))); + PlatformDataIntegrityException result = assertThrows(PlatformDataIntegrityException.class, () -> { + underTest.extractUniqueId(json); + }); + assertTrue(result.getDefaultUserMessage().contains("\"NRCID1\", \"NRCID2\"")); + } + + @Test + public void extractUniqueIdNoDataTest() throws JsonProcessingException { + String json = createResponseObjectArrayData(() -> "NoData", data -> null); + PlatformDataIntegrityException result = assertThrows(PlatformDataIntegrityException.class, () -> { + underTest.extractUniqueId(json); + }); + assertEquals("NoData", result.getDefaultUserMessage()); + } + + @Test + public void createTokenTest() throws IOException { + mockTokenGeneration(); + mockOkHttpCall(request -> { + List auhtorizationHeaders = request.headers("Authorization"); + assertTrue(auhtorizationHeaders.isEmpty()); + assertEquals(request.header("mcix-subscription-key"), "subscriptionKey"); + assertEquals(request.header("mcix-subscription-id"), "subscriptionId"); + assertEquals(request.header("Content-Type"), "application/x-www-form-urlencoded"); + BufferedSink sink = Okio.buffer(Okio.sink(new ByteArrayOutputStream())); + request.body().writeTo(sink); + String urlEncodedForm = sink.getBuffer().readUtf8(); + assertTrue(urlEncodedForm.contains("grant_type=password")); + assertTrue(urlEncodedForm.contains("userName=testUser")); + assertTrue(urlEncodedForm.contains("password=testPassword")); + + return createOkhttpResponse(request, 200, createValidToken()); + }); + CreditBureauToken token = underTest.createToken(1L); + assertNotNull(token); + } + + @NotNull + private String createValidToken() throws JsonProcessingException { + ObjectNode jsonResponse = mapper.createObjectNode(); + jsonResponse.put("access_token", "AccessToken"); + jsonResponse.put("expires_in", 3600); + jsonResponse.put("token_type", "Bearer"); + jsonResponse.put("userName", "testUser"); + jsonResponse.put(".issued", "sample"); + jsonResponse.put(".expires", ZonedDateTime.now(ZoneId.systemDefault()).plusSeconds(3600) + .format(new DateTimeFormatterBuilder().appendPattern("EEE, dd MMM yyyy kk:mm:ss zzz").toFormatter())); + return mapper.writeValueAsString(jsonResponse); + } + + private JsonCommand initialJsonCommand() throws JsonProcessingException { + ObjectNode command = mapper.createObjectNode(); + command.put("NRC", "NRCID"); + command.put("creditBureauID", "1"); // Must match to the mocked config + String json = mapper.writeValueAsString(command); + return JsonCommand.from(json, JsonParser.parseString(json), fromJsonHelper, null, 1L, 2L, 3L, 4L, null, null, null, null, null, + null, null, null); + } + + private void mockTokenGeneration() { + ArgumentCaptor tokenCaptor = ArgumentCaptor.forClass(CreditBureauToken.class); + when(tokenRepositoryWrapper.getToken()).thenAnswer(answer -> { + if (tokenCaptor.getAllValues().isEmpty()) { + return null; + } + return tokenCaptor.getValue(); + }); + doNothing().when(tokenRepositoryWrapper).save(tokenCaptor.capture()); + } + + @Test + public void getCreditReportFromThitsaWorksSuccessTest() throws IOException { + mockTokenGeneration(); + mockOkHttpCall(request -> { + // NRC Call + if (request.url().host().equals("search.report.url")) { + return createOkhttpResponse(request, createResponseObjectArrayData(() -> "Success", + data -> data.add(mapper.createObjectNode().put("UniqueID", "123456")))); + } + if (request.url().host().equals("credit.report.url")) { + assertTrue(request.url().encodedPath().endsWith("/123456")); + return createOkhttpResponse(request, createResponseObjectObjectData(() -> "Success", data -> { + ObjectNode borrowerData = mapper.createObjectNode(); + borrowerData.put("Name", "Test Name"); + borrowerData.put("Gender", "Male"); + borrowerData.put("Address", "Test Address"); + data.set("BorrowerInfo", borrowerData); + data.set("CreditScore", mapper.createObjectNode().put("Score", "123")); + data.set("ActiveLoans", mapper.createArrayNode().add("Loan1").add("Loan2")); + data.set("WriteOffLoans", mapper.createArrayNode().add("Loan3").add("Loan4")); + return data; + })); + } + if (request.url().host().equals("token.url")) { + return createOkhttpResponse(request, 200, createValidToken()); + } + return createOkhttpResponse(request, 404, "Not Found"); + }); + + CreditBureauReportData result = underTest.getCreditReportFromThitsaWorks(initialJsonCommand()); + assertNotNull(result); + } + + @Test + public void addCreditReportTest() throws IOException { + mockTokenGeneration(); + + when(configurationRepositoryWrapper.getCreditBureauConfigData(1, "addCreditReporturl")) + .thenReturn(new CreditBureauConfiguration().setValue("https://addcredit.report.url/api/")); + String jsonResponse = createResponseObjectArrayData(() -> "ADD_CREDIT_RESPONSE", data -> data); + + Path temp = Files.createTempFile("add_credit_report" + System.currentTimeMillis(), ".data"); + Files.writeString(temp, "test"); + + mockOkHttpCall(request -> { + if (request.url().host().equals("addcredit.report.url")) { + return createOkhttpResponse(request, jsonResponse); + } + if (request.url().host().equals("token.url")) { + return createOkhttpResponse(request, 200, createValidToken()); + } + return createOkhttpResponse(request, 404, "Not Found"); + }); + FormDataContentDisposition fileDetail = mock(FormDataContentDisposition.class); + when(fileDetail.getFileName()).thenReturn("test.pdf"); + + PlatformDataIntegrityException result = assertThrows(PlatformDataIntegrityException.class, + () -> underTest.addCreditReport(1L, temp.toFile(), fileDetail)); + assertEquals("ADD_CREDIT_RESPONSE", result.getDefaultUserMessage()); + } + + // TODO: if no borrower is throw NPE + // @Test + public void getCreditReportFromThitsaWorksEmptyBorrowerTest() throws IOException { + mockTokenGeneration(); + mockOkHttpCall(request -> { + // NRC Call + if (request.url().host().equals("search.report.url")) { + return createOkhttpResponse(request, createResponseObjectArrayData(() -> "Success", + data -> data.add(mapper.createObjectNode().put("UniqueID", "123456")))); + } + if (request.url().host().equals("credit.report.url")) { + assertTrue(request.url().encodedPath().endsWith("/123456")); + return createOkhttpResponse(request, createResponseObjectObjectData(() -> "Success", data -> { + data.set("CreditScore", mapper.createObjectNode().put("Score", "123")); + data.set("ActiveLoans", mapper.createArrayNode().add("Loan1").add("Loan2")); + data.set("WriteOffLoans", mapper.createArrayNode().add("Loan3").add("Loan4")); + return data; + })); + } + if (request.url().host().equals("token.url")) { + return createOkhttpResponse(request, 200, createValidToken()); + } + return createOkhttpResponse(request, 404, "Not Found"); + }); + + CreditBureauReportData result = underTest.getCreditReportFromThitsaWorks(initialJsonCommand()); + assertNotNull(result); + assertNull(result.getGender()); + assertNotNull(result.getCreditScore()); + } + + // TODO: empty gender not handler correctly (NPE) + // @Test + public void getCreditReportFromThitsaWorksNoGenderTest() throws IOException { + mockTokenGeneration(); + mockOkHttpCall(request -> { + // NRC Call + if (request.url().host().equals("search.report.url")) { + return createOkhttpResponse(request, createResponseObjectArrayData(() -> "Success", + data -> data.add(mapper.createObjectNode().put("UniqueID", "123456")))); + } + if (request.url().host().equals("credit.report.url")) { + assertTrue(request.url().encodedPath().endsWith("/123456")); + return createOkhttpResponse(request, createResponseObjectObjectData(() -> "Success", data -> { + ObjectNode borrowerData = mapper.createObjectNode(); + borrowerData.put("Name", "Test Name"); + borrowerData.put("Address", "Test Address"); + data.set("BorrowerInfo", borrowerData); + data.set("CreditScore", mapper.createObjectNode().put("Score", "123")); + data.set("ActiveLoans", mapper.createArrayNode().add("Loan1").add("Loan2")); + data.set("WriteOffLoans", mapper.createArrayNode().add("Loan3").add("Loan4")); + return data; + })); + } + if (request.url().host().equals("token.url")) { + return createOkhttpResponse(request, 200, createValidToken()); + } + return createOkhttpResponse(request, 404, "Not Found"); + }); + + CreditBureauReportData result = underTest.getCreditReportFromThitsaWorks(initialJsonCommand()); + assertNotNull(result); + assertNull(result.getGender()); + assertNotNull(result.getCreditScore()); + } + + // TODO: null credit script invalid result + // @Test + public void getCreditReportFromThitsaWorksNoLoansTest() throws IOException { + mockTokenGeneration(); + mockOkHttpCall(request -> { + // NRC Call + if (request.url().host().equals("search.report.url")) { + return createOkhttpResponse(request, createResponseObjectArrayData(() -> "Success", + data -> data.add(mapper.createObjectNode().put("UniqueID", "123456")))); + } + if (request.url().host().equals("credit.report.url")) { + assertTrue(request.url().encodedPath().endsWith("/123456")); + return createOkhttpResponse(request, createResponseObjectObjectData(() -> "Success", data -> { + ObjectNode borrowerData = mapper.createObjectNode(); + borrowerData.put("Name", "Test Name"); + borrowerData.put("Gender", "Male"); + borrowerData.put("Address", "Test Address"); + data.set("BorrowerInfo", borrowerData); + return data; + })); + } + if (request.url().host().equals("token.url")) { + return createOkhttpResponse(request, 200, createValidToken()); + } + return createOkhttpResponse(request, 404, "Not Found"); + }); + + CreditBureauReportData result = underTest.getCreditReportFromThitsaWorks(initialJsonCommand()); + assertNotNull(result); + assertNotNull(result.getGender()); + assertNull(result.getCreditScore()); + assertNull(result.getOpenAccounts()); + assertNull(result.getClosedAccounts()); + } + +} diff --git a/integration-tests/dependencies.gradle b/integration-tests/dependencies.gradle index 7aa508437..69569b6b2 100644 --- a/integration-tests/dependencies.gradle +++ b/integration-tests/dependencies.gradle @@ -43,4 +43,5 @@ dependencies { testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' + testImplementation 'com.github.tomakehurst:wiremock-jre8:2.35.0' } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/CreditBureauTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/CreditBureauTest.java new file mode 100644 index 000000000..7d11d8c6c --- /dev/null +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/CreditBureauTest.java @@ -0,0 +1,187 @@ +/** + * 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 com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.junit5.WireMockExtension; +import com.google.gson.Gson; +import com.google.gson.JsonParser; +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.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatterBuilder; +import java.util.List; +import java.util.Map; +import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauReportData; +import org.apache.fineract.integrationtests.common.CreditBureauConfigurationHelper; +import org.apache.fineract.integrationtests.common.CreditBureauIntegrationHelper; +import org.apache.fineract.integrationtests.common.Utils; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CreditBureauTest { + + private static final Logger LOG = LoggerFactory.getLogger(CreditBureauTest.class); + private ResponseSpecification responseSpec; + private RequestSpecification requestSpec; + + private static final ObjectMapper MAPPER = new ObjectMapper(); + + @RegisterExtension + static WireMockExtension wm = WireMockExtension.newInstance().options(wireMockConfig().port(3558)).build(); + + @BeforeEach + public void setup() { + Utils.initializeRESTAssured(); + this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build(); + this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey()); + this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build(); + configureCreditBureauService(); + } + + private void configureCreditBureauService() { + Object organisations = CreditBureauConfigurationHelper.getOrganizationCreditBureauConfiguration(this.requestSpec, + this.responseSpec); + + if (new Gson().fromJson(String.valueOf(organisations), List.class).isEmpty()) { + CreditBureauConfigurationHelper.addOrganisationCreditBureau(this.requestSpec, this.responseSpec, "1", "SAMPLE_ALIAS", true); + } else { + CreditBureauConfigurationHelper.updateOrganisationCreditBureau(this.requestSpec, this.responseSpec, "1", true); + } + List> configurations = CreditBureauConfigurationHelper.getCreditBureauConfiguration(requestSpec, responseSpec, + "1"); + Assertions.assertNotNull(configurations); + Map currentConfiguration = io.vavr.collection.List.ofAll(configurations) + .toMap(k -> String.valueOf(k.get("configurationKey")).toUpperCase(), v -> (int) v.get("creditBureauConfigurationId")) + .toJavaMap(); + final Object usernameConfigurationId = CreditBureauConfigurationHelper.updateCreditBureauConfiguration(this.requestSpec, + this.responseSpec, currentConfiguration.get("USERNAME").intValue(), "USERNAME", "testUser"); + Assertions.assertNotNull(usernameConfigurationId); + final Object passwordConfigurationId = CreditBureauConfigurationHelper.updateCreditBureauConfiguration(this.requestSpec, + this.responseSpec, currentConfiguration.get("PASSWORD").intValue(), "PASSWORD", "testPassword"); + Assertions.assertNotNull(passwordConfigurationId); + final Object creditReportUrlConfigurationId = CreditBureauConfigurationHelper.updateCreditBureauConfiguration(this.requestSpec, + this.responseSpec, currentConfiguration.get("CREDITREPORTURL").intValue(), "CREDITREPORTURL", + "http://localhost:3558/report/"); + Assertions.assertNotNull(creditReportUrlConfigurationId); + final Object searchUrlConfigurationId = CreditBureauConfigurationHelper.updateCreditBureauConfiguration(this.requestSpec, + this.responseSpec, currentConfiguration.get("SEARCHURL").intValue(), "SEARCHURL", "http://localhost:3558/search/"); + Assertions.assertNotNull(searchUrlConfigurationId); + final Object tokenUrlConfigurationId = CreditBureauConfigurationHelper.updateCreditBureauConfiguration(this.requestSpec, + this.responseSpec, currentConfiguration.get("TOKENURL").intValue(), "TOKENURL", "http://localhost:3558/token/"); + Assertions.assertNotNull(tokenUrlConfigurationId); + final Object subscriptionIdConfigurationId = CreditBureauConfigurationHelper.updateCreditBureauConfiguration(this.requestSpec, + this.responseSpec, currentConfiguration.get("SUBSCRIPTIONID").intValue(), "SUBSCRIPTIONID", "subscriptionID123"); + Assertions.assertNotNull(subscriptionIdConfigurationId); + final Object subscriptionKeyConfigurationId = CreditBureauConfigurationHelper.updateCreditBureauConfiguration(this.requestSpec, + this.responseSpec, currentConfiguration.get("SUBSCRIPTIONKEY").intValue(), "SUBSCRIPTIONKEY", "subscriptionKey456"); + Assertions.assertNotNull(subscriptionKeyConfigurationId); + final Object addCreditReportUrlId = CreditBureauConfigurationHelper.updateCreditBureauConfiguration(this.requestSpec, + this.responseSpec, currentConfiguration.get("ADDCREDITREPORTURL").intValue(), "addCreditReporturl", + "http://localhost:3558/upload/"); + Assertions.assertNotNull(addCreditReportUrlId); + + } + + @Test + public void creditBureauIntegrationTest() throws JsonProcessingException { + ObjectNode jsonResponse = MAPPER.createObjectNode(); + jsonResponse.put("access_token", "AccessToken"); + jsonResponse.put("expires_in", 3600); + jsonResponse.put("token_type", "Bearer"); + jsonResponse.put("userName", "testUser"); + jsonResponse.put(".issued", "sample"); + jsonResponse.put(".expires", ZonedDateTime.now(ZoneId.systemDefault()).plusSeconds(3600) + .format(new DateTimeFormatterBuilder().appendPattern("EEE, dd MMM yyyy kk:mm:ss zzz").toFormatter())); + wm.stubFor(WireMock.post("/token/").willReturn(WireMock.jsonResponse(MAPPER.writeValueAsString(jsonResponse), 200))); + wm.stubFor(WireMock.post("/search/NRC213") + .willReturn(WireMock.jsonResponse("{\"ResponseMessage\":\"OK\",\"Data\":[{\"UniqueID\":\"123456\"}]}", 200))); + wm.stubFor(WireMock.get("/report/123456").willReturn( + WireMock.jsonResponse("{\"ResponseMessage\":\"OK\",\"Data\":{" + "\"BorrowerInfo\":{" + "\"Name\":\"Test Name\"," + + "\"Gender\":\"male\"," + "\"Address\":\"Test Address\"" + "}," + "\"CreditScore\": {\"Score\": \"500\"}," + + "\"ActiveLoans\": [\"Loan1\", \"Loan2\"]," + "\"WriteOffLoans\": [\"Loan3\", \"Loan4\"]" + "}}", 200))); + + Object serviceResult = CreditBureauIntegrationHelper.getCreditReport(this.requestSpec, this.responseSpec, "1", "NRC213"); + Assertions.assertNotNull(serviceResult); + Gson gson = new Gson(); + CreditBureauReportData responseData = gson.fromJson( + gson.toJson(JsonParser.parseString(String.valueOf(serviceResult)).getAsJsonObject().get("creditBureauReportData")), + CreditBureauReportData.class); + Assertions.assertEquals("\"Test Name\"", responseData.getName()); + Assertions.assertEquals("{\"Score\":\"500\"}", responseData.getCreditScore()); + + Assertions.assertEquals("\"male\"", responseData.getGender()); + Assertions.assertEquals("\"Test Address\"", responseData.getAddress()); + + Assertions.assertEquals(2, responseData.getClosedAccounts().length); + Assertions.assertEquals(2, responseData.getOpenAccounts().length); + Assertions.assertEquals("\"Loan3\"", responseData.getClosedAccounts()[0]); + Assertions.assertEquals("\"Loan4\"", responseData.getClosedAccounts()[1]); + Assertions.assertEquals("\"Loan1\"", responseData.getOpenAccounts()[0]); + Assertions.assertEquals("\"Loan2\"", responseData.getOpenAccounts()[1]); + } + + @Test + public void creditBureauNoLoanTest() throws JsonProcessingException { + ObjectNode jsonResponse = MAPPER.createObjectNode(); + jsonResponse.put("access_token", "AccessToken"); + jsonResponse.put("expires_in", 3600); + jsonResponse.put("token_type", "Bearer"); + jsonResponse.put("userName", "testUser"); + jsonResponse.put(".issued", "sample"); + jsonResponse.put(".expires", ZonedDateTime.now(ZoneId.systemDefault()).plusSeconds(3600) + .format(new DateTimeFormatterBuilder().appendPattern("EEE, dd MMM yyyy kk:mm:ss zzz").toFormatter())); + wm.stubFor(WireMock.post("/token/").willReturn(WireMock.jsonResponse(MAPPER.writeValueAsString(jsonResponse), 200))); + wm.stubFor(WireMock.post("/search/NRC213") + .willReturn(WireMock.jsonResponse("{\"ResponseMessage\":\"OK\",\"Data\":[{\"UniqueID\":\"123456\"}]}", 200))); + wm.stubFor(WireMock.get("/report/123456") + .willReturn(WireMock.jsonResponse("{\"ResponseMessage\":\"OK\",\"Data\":{" + "\"BorrowerInfo\":{" + + "\"Name\":\"Test Name\"," + "\"Gender\":\"male\"," + "\"Address\":\"Test Address\"" + "}," + + "\"CreditScore\": {\"Score\": \"500\"}," + "\"ActiveLoans\": []," + "\"WriteOffLoans\": []" + "}}", 200))); + + Object serviceResult = CreditBureauIntegrationHelper.getCreditReport(this.requestSpec, this.responseSpec, "1", "NRC213"); + Assertions.assertNotNull(serviceResult); + Gson gson = new Gson(); + CreditBureauReportData responseData = gson.fromJson( + gson.toJson(JsonParser.parseString(String.valueOf(serviceResult)).getAsJsonObject().get("creditBureauReportData")), + CreditBureauReportData.class); + Assertions.assertEquals("\"Test Name\"", responseData.getName()); + Assertions.assertEquals("{\"Score\":\"500\"}", responseData.getCreditScore()); + + Assertions.assertEquals("\"male\"", responseData.getGender()); + Assertions.assertEquals("\"Test Address\"", responseData.getAddress()); + + Assertions.assertEquals(0, responseData.getClosedAccounts().length); + Assertions.assertEquals(0, responseData.getOpenAccounts().length); + } + +} diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/CreditBureauConfigurationHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/CreditBureauConfigurationHelper.java index 62c68d956..70bb3b43b 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/CreditBureauConfigurationHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/CreditBureauConfigurationHelper.java @@ -21,9 +21,12 @@ package org.apache.fineract.integrationtests.common; import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,18 +43,32 @@ public class CreditBureauConfigurationHelper { this.responseSpec = responseSpec; } + public static List> getCreditBureauConfiguration(RequestSpecification requestSpec, + ResponseSpecification responseSpec, String creditBureauId) { + LOG.info("---------------------------------GET A CREDIT_BUREAU_CONFIGURATION---------------------------------------------"); + final String CREDITBUREAU_CONFIGURATION_URL = "/fineract-provider/api/v1/CreditBureauConfiguration/config/" + creditBureauId + "?" + + Utils.TENANT_IDENTIFIER; + return JsonPath.from(Utils.performServerGet(requestSpec, responseSpec, CREDITBUREAU_CONFIGURATION_URL)).getList(""); + } + public static Integer createCreditBureauConfiguration(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, String configKey) { return createCreditBureauConfiguration(requestSpec, responseSpec, "1", configKey); } public static Integer createCreditBureauConfiguration(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, - final String creditBureauId, String configKey) { + final String creditBureauId, String configKey, String value, String description) { LOG.info("---------------------------------CREATING A CREDIT_BUREAU_CONFIGURATION---------------------------------------------"); - final String CREDITBUREAU_CONFIGURATION_URL = " /fineract-provider/api/v1/CreditBureauConfiguration/configuration/" + creditBureauId + final String CREDITBUREAU_CONFIGURATION_URL = "/fineract-provider/api/v1/CreditBureauConfiguration/configuration/" + creditBureauId + "?" + Utils.TENANT_IDENTIFIER; return Utils.performServerPost(requestSpec, responseSpec, CREDITBUREAU_CONFIGURATION_URL, - creditBureauConfigurationAsJson(configKey, "testConfigKeyValue", "description"), "resourceId"); + creditBureauConfigurationAsJson(configKey, value, description), "resourceId"); + } + + public static Integer createCreditBureauConfiguration(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final String creditBureauId, String configKey) { + LOG.info("---------------------------------CREATING A CREDIT_BUREAU_CONFIGURATION---------------------------------------------"); + return createCreditBureauConfiguration(requestSpec, responseSpec, creditBureauId, configKey, "testConfigKeyValue", "description"); } /* @@ -63,7 +80,8 @@ public class CreditBureauConfigurationHelper { public static String updateCreditBureauConfiguration(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, final Integer ConfigurationId) { - Object configurationObject = updateCreditBureauConfiguration(requestSpec, responseSpec, ConfigurationId, "updateConfigKeyValue"); + Object configurationObject = updateCreditBureauConfiguration(requestSpec, responseSpec, ConfigurationId, null, + "updateConfigKeyValue"); // Convert the Object to String and fetch updated value Gson gson = new Gson(); String result = gson.toJson(configurationObject); @@ -74,12 +92,52 @@ public class CreditBureauConfigurationHelper { } public static Object updateCreditBureauConfiguration(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, - final Integer ConfigurationId, final String updateConfigKeyValue) { + final Integer ConfigurationId, String configKey, final String updateConfigKeyValue) { LOG.info("---------------------------------UPDATING A CREDIT_BUREAU_CONFIGURATION---------------------------------------------"); - final String CREDITBUREAU_CONFIGURATION_URL = " /fineract-provider/api/v1/CreditBureauConfiguration/configuration/" - + ConfigurationId + "?" + Utils.TENANT_IDENTIFIER; + final String CREDITBUREAU_CONFIGURATION_URL = "/fineract-provider/api/v1/CreditBureauConfiguration/configuration/" + ConfigurationId + + "?" + Utils.TENANT_IDENTIFIER; return Utils.performServerPut(requestSpec, responseSpec, CREDITBUREAU_CONFIGURATION_URL, - updateCreditBureauConfigurationAsJson("updateConfigKeyValue", "description"), "changes"); + updateCreditBureauConfigurationAsJson(configKey, updateConfigKeyValue), "changes"); + } + + public static Object getOrganizationCreditBureauConfiguration(final RequestSpecification requestSpec, + final ResponseSpecification responseSpec) { + LOG.info("---------------------------------GETTING A CREDIT_BUREAU_CONFIGURATION---------------------------------------------"); + final String CREDITBUREAU_CONFIGURATION_URL = "/fineract-provider/api/v1/CreditBureauConfiguration/organisationCreditBureau?" + + Utils.TENANT_IDENTIFIER; + return Utils.performServerGet(requestSpec, responseSpec, CREDITBUREAU_CONFIGURATION_URL, null); + } + + public static Object addOrganisationCreditBureau(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final String creditBureauId, String alias, boolean isActive) { + LOG.info("---------------------------------CREATING A CREDIT_BUREAU_CONFIGURATION---------------------------------------------"); + final String URL = "/fineract-provider/api/v1/CreditBureauConfiguration/organisationCreditBureau/" + creditBureauId + "?" + + Utils.TENANT_IDENTIFIER; + return Utils.performServerPost(requestSpec, responseSpec, URL, addOrganizationCreditBureauCreateAsJson(alias, isActive), null); + } + + public static Object updateOrganisationCreditBureau(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final String creditBureauId, boolean isActive) { + LOG.info("---------------------------------CREATING A CREDIT_BUREAU_CONFIGURATION---------------------------------------------"); + final String URL = "/fineract-provider/api/v1/CreditBureauConfiguration/organisationCreditBureau?" + Utils.TENANT_IDENTIFIER; + return Utils.performServerPut(requestSpec, responseSpec, URL, updateOrganizationCreditBureauCreateAsJson(creditBureauId, isActive), + null); + } + + public static String addOrganizationCreditBureauCreateAsJson(final String alias, final boolean isActive) { + final HashMap map = new HashMap<>(); + map.put("alias", alias); + map.put("isActive", isActive); + LOG.info("map : {}", map); + return new Gson().toJson(map); + } + + public static String updateOrganizationCreditBureauCreateAsJson(final String creditBureauId, final boolean isActive) { + final HashMap map = new HashMap<>(); + map.put("creditBureauId", creditBureauId); + map.put("isActive", isActive); + LOG.info("map : {}", map); + return new Gson().toJson(map); } public static String creditBureauConfigurationAsJson(final String configkey, final String value, final String description) { @@ -91,10 +149,12 @@ public class CreditBureauConfigurationHelper { return new Gson().toJson(map); } - public static String updateCreditBureauConfigurationAsJson(final String value, final String description) { + public static String updateCreditBureauConfigurationAsJson(final String configKey, final String value) { final HashMap map = new HashMap<>(); + if (configKey != null) { + map.put("configkey", configKey); + } map.put("value", value); - map.put("description", description); LOG.info("map : {}", map); return new Gson().toJson(map); } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/CreditBureauIntegrationHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/CreditBureauIntegrationHelper.java new file mode 100644 index 000000000..4e19d0bfe --- /dev/null +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/CreditBureauIntegrationHelper.java @@ -0,0 +1,69 @@ +/** + * 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.common; + +import static io.restassured.RestAssured.given; + +import com.google.gson.Gson; +import io.restassured.specification.RequestSpecification; +import io.restassured.specification.ResponseSpecification; +import java.io.File; +import java.util.HashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CreditBureauIntegrationHelper { + + private static final Logger LOG = LoggerFactory.getLogger(CreditBureauIntegrationHelper.class); + private final RequestSpecification requestSpec; + private final ResponseSpecification responseSpec; + + public CreditBureauIntegrationHelper(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) { + this.requestSpec = requestSpec; + this.responseSpec = responseSpec; + } + + public static Object getCreditReport(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final String creditBureauId, String nrc) { + LOG.info("---------------------------------CREATING A CREDIT_BUREAU_CONFIGURATION---------------------------------------------"); + final String CREDITBUREAU_CONFIGURATION_URL = "/fineract-provider/api/v1/creditBureauIntegration/creditReport?" + + Utils.TENANT_IDENTIFIER; + return Utils.performServerPost(requestSpec, responseSpec, CREDITBUREAU_CONFIGURATION_URL, + createGetCreditReportAsJson(creditBureauId, nrc), null); + } + + public static String uploadCreditReport(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final String creditBureauId, File file) { + LOG.info("---------------------------------CREATING A CREDIT_BUREAU_CONFIGURATION---------------------------------------------"); + final String CREDITBUREAU_CONFIGURATION_URL = "/fineract-provider/api/v1/creditBureauIntegration/addCreditReport?" + + Utils.TENANT_IDENTIFIER; + return given().spec(requestSpec).queryParam("creditBureauId", creditBureauId).contentType("multipart/form-data") + .multiPart("file", file).expect().spec(responseSpec).log().ifError().when().post(CREDITBUREAU_CONFIGURATION_URL).andReturn() + .asString(); + } + + public static String createGetCreditReportAsJson(final String creditBureauId, final String nrc) { + final HashMap map = new HashMap<>(); + map.put("creditBureauID", creditBureauId); + map.put("NRC", nrc); + LOG.info("map : {}", map); + return new Gson().toJson(map); + } + +}