FINERACT-2418: Add originators details to external business events
This commit is contained in:
committed by
Arnold Gálovics
parent
288038d7bb
commit
c57f44d3f0
@@ -25,6 +25,10 @@ dependencies {
|
||||
// implementation dependencies are directly used (compiled against) in src/main (and src/test)
|
||||
//
|
||||
implementation(project(path: ':fineract-core'))
|
||||
implementation('org.apache.avro:avro')
|
||||
implementation(
|
||||
project(path: ':fineract-avro-schemas')
|
||||
)
|
||||
implementation(project(path: ':fineract-loan'))
|
||||
|
||||
implementation(
|
||||
|
||||
+11
@@ -22,12 +22,23 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
public interface LoanOriginatorMappingRepository
|
||||
extends JpaRepository<LoanOriginatorMapping, Long>, JpaSpecificationExecutor<LoanOriginatorMapping> {
|
||||
|
||||
List<LoanOriginatorMapping> findByLoanId(Long loanId);
|
||||
|
||||
@Query("""
|
||||
SELECT m FROM LoanOriginatorMapping m
|
||||
JOIN FETCH m.originator o
|
||||
LEFT JOIN FETCH o.originatorType
|
||||
LEFT JOIN FETCH o.channelType
|
||||
WHERE m.loanId = :loanId
|
||||
""")
|
||||
List<LoanOriginatorMapping> findByLoanIdWithOriginatorDetails(@Param("loanId") Long loanId);
|
||||
|
||||
boolean existsByLoanId(Long loanId);
|
||||
|
||||
boolean existsByOriginatorId(Long originatorId);
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* 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.portfolio.loanorigination.enricher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.avro.loan.v1.LoanAccountDataV1;
|
||||
import org.apache.fineract.avro.loan.v1.OriginatorDetailsV1;
|
||||
import org.apache.fineract.infrastructure.core.service.DataEnricher;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginator;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginatorMapping;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginatorMappingRepository;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(value = "fineract.module.loan-origination.enabled", havingValue = "true")
|
||||
public class LoanAccountDataV1OriginatorEnricher implements DataEnricher<LoanAccountDataV1> {
|
||||
|
||||
private final LoanOriginatorMappingRepository loanOriginatorMappingRepository;
|
||||
private final LoanOriginatorAvroMapper loanOriginatorAvroMapper;
|
||||
|
||||
@Override
|
||||
public boolean isDataTypeSupported(final Class<LoanAccountDataV1> dataType) {
|
||||
return dataType.isAssignableFrom(LoanAccountDataV1.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enrich(final LoanAccountDataV1 data) {
|
||||
if (data == null || data.getId() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<LoanOriginatorMapping> mappings = loanOriginatorMappingRepository.findByLoanIdWithOriginatorDetails(data.getId());
|
||||
if (mappings == null || mappings.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<OriginatorDetailsV1> originators = new ArrayList<>();
|
||||
for (LoanOriginatorMapping mapping : mappings) {
|
||||
final LoanOriginator originator = mapping.getOriginator();
|
||||
if (originator != null) {
|
||||
final OriginatorDetailsV1 originatorDetails = loanOriginatorAvroMapper.toAvro(originator);
|
||||
if (originatorDetails != null) {
|
||||
originators.add(originatorDetails);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!originators.isEmpty()) {
|
||||
data.setOriginators(originators);
|
||||
}
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* 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.portfolio.loanorigination.enricher;
|
||||
|
||||
import org.apache.fineract.avro.generic.v1.CodeValueDataV1;
|
||||
import org.apache.fineract.avro.loan.v1.OriginatorDetailsV1;
|
||||
import org.apache.fineract.infrastructure.codes.domain.CodeValue;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginator;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@ConditionalOnProperty(value = "fineract.module.loan-origination.enabled", havingValue = "true")
|
||||
public class LoanOriginatorAvroMapper {
|
||||
|
||||
/**
|
||||
* Converts a LoanOriginator entity to OriginatorDetailsV1 Avro
|
||||
*/
|
||||
public OriginatorDetailsV1 toAvro(final LoanOriginator originator) {
|
||||
if (originator == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final OriginatorDetailsV1.Builder builder = OriginatorDetailsV1.newBuilder();
|
||||
|
||||
builder.setId(originator.getId());
|
||||
builder.setExternalId(originator.getExternalId() != null ? originator.getExternalId().getValue() : null);
|
||||
builder.setName(originator.getName());
|
||||
builder.setStatus(originator.getStatus() != null ? originator.getStatus().getValue() : null);
|
||||
builder.setOriginatorType(mapCodeValue(originator.getOriginatorType()));
|
||||
builder.setChannelType(mapCodeValue(originator.getChannelType()));
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a CodeValue entity to CodeValueDataV1 Avro
|
||||
*/
|
||||
private CodeValueDataV1 mapCodeValue(CodeValue codeValue) {
|
||||
if (codeValue == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CodeValueDataV1.Builder builder = CodeValueDataV1.newBuilder();
|
||||
builder.setId(codeValue.getId());
|
||||
builder.setName(codeValue.getLabel());
|
||||
builder.setPosition(codeValue.getPosition());
|
||||
builder.setDescription(codeValue.getDescription());
|
||||
builder.setActive(codeValue.isActive());
|
||||
builder.setMandatory(codeValue.isMandatory());
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* 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.portfolio.loanorigination.enricher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1;
|
||||
import org.apache.fineract.avro.loan.v1.OriginatorDetailsV1;
|
||||
import org.apache.fineract.infrastructure.core.service.DataEnricher;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginator;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginatorMapping;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginatorMappingRepository;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(value = "fineract.module.loan-origination.enabled", havingValue = "true")
|
||||
public class LoanTransactionDataV1OriginatorEnricher implements DataEnricher<LoanTransactionDataV1> {
|
||||
|
||||
private final LoanOriginatorMappingRepository loanOriginatorMappingRepository;
|
||||
private final LoanOriginatorAvroMapper loanOriginatorAvroMapper;
|
||||
|
||||
@Override
|
||||
public boolean isDataTypeSupported(final Class<LoanTransactionDataV1> dataType) {
|
||||
return dataType.isAssignableFrom(LoanTransactionDataV1.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enrich(final LoanTransactionDataV1 data) {
|
||||
if (data == null || data.getLoanId() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<LoanOriginatorMapping> mappings = loanOriginatorMappingRepository.findByLoanIdWithOriginatorDetails(data.getLoanId());
|
||||
if (mappings == null || mappings.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<OriginatorDetailsV1> originators = new ArrayList<>();
|
||||
for (LoanOriginatorMapping mapping : mappings) {
|
||||
final LoanOriginator originator = mapping.getOriginator();
|
||||
if (originator != null) {
|
||||
final OriginatorDetailsV1 originatorDetails = loanOriginatorAvroMapper.toAvro(originator);
|
||||
if (originatorDetails != null) {
|
||||
originators.add(originatorDetails);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!originators.isEmpty()) {
|
||||
data.setOriginators(originators);
|
||||
}
|
||||
}
|
||||
}
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
* 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.portfolio.loanorigination.enricher;
|
||||
|
||||
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.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.avro.loan.v1.LoanAccountDataV1;
|
||||
import org.apache.fineract.avro.loan.v1.OriginatorDetailsV1;
|
||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginator;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginatorMapping;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginatorMappingRepository;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginatorStatus;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class LoanAccountDataV1OriginatorEnricherTest {
|
||||
|
||||
@Mock
|
||||
private LoanOriginatorMappingRepository loanOriginatorMappingRepository;
|
||||
|
||||
@Mock
|
||||
private LoanOriginatorAvroMapper loanOriginatorAvroMapper;
|
||||
|
||||
@InjectMocks
|
||||
private LoanAccountDataV1OriginatorEnricher enricher;
|
||||
|
||||
private LoanAccountDataV1 loanAccountData;
|
||||
private Long loanId;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
loanId = 1L;
|
||||
loanAccountData = new LoanAccountDataV1();
|
||||
loanAccountData.setId(loanId);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsDataTypeSupported() {
|
||||
assertTrue(enricher.isDataTypeSupported(LoanAccountDataV1.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEnrich_WithOriginators() {
|
||||
// Given
|
||||
final LoanOriginator originator = createTestOriginator(1L, "test-originator-1", "Test Originator 1");
|
||||
final LoanOriginatorMapping mapping = LoanOriginatorMapping.create(loanId, originator);
|
||||
final List<LoanOriginatorMapping> mappings = List.of(mapping);
|
||||
|
||||
final OriginatorDetailsV1 originatorDetails = createOriginatorDetailsV1(1L, "test-originator-1", "Test Originator 1");
|
||||
|
||||
when(loanOriginatorMappingRepository.findByLoanIdWithOriginatorDetails(loanId)).thenReturn(mappings);
|
||||
when(loanOriginatorAvroMapper.toAvro(originator)).thenReturn(originatorDetails);
|
||||
|
||||
// When
|
||||
enricher.enrich(loanAccountData);
|
||||
|
||||
// Then
|
||||
verify(loanOriginatorMappingRepository).findByLoanIdWithOriginatorDetails(loanId);
|
||||
verify(loanOriginatorAvroMapper).toAvro(originator);
|
||||
assertNotNull(loanAccountData.getOriginators());
|
||||
assertEquals(1, loanAccountData.getOriginators().size());
|
||||
assertEquals("test-originator-1", loanAccountData.getOriginators().getFirst().getExternalId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEnrich_WithMultipleOriginators() {
|
||||
// Given
|
||||
final LoanOriginator originator1 = createTestOriginator(1L, "test-originator-1", "Test Originator 1");
|
||||
final LoanOriginator originator2 = createTestOriginator(2L, "test-originator-2", "Test Originator 2");
|
||||
final List<LoanOriginatorMapping> mappings = List.of(LoanOriginatorMapping.create(loanId, originator1),
|
||||
LoanOriginatorMapping.create(loanId, originator2));
|
||||
|
||||
final OriginatorDetailsV1 details1 = createOriginatorDetailsV1(1L, "test-originator-1", "Test Originator 1");
|
||||
final OriginatorDetailsV1 details2 = createOriginatorDetailsV1(2L, "test-originator-2", "Test Originator 2");
|
||||
|
||||
when(loanOriginatorMappingRepository.findByLoanIdWithOriginatorDetails(loanId)).thenReturn(mappings);
|
||||
when(loanOriginatorAvroMapper.toAvro(originator1)).thenReturn(details1);
|
||||
when(loanOriginatorAvroMapper.toAvro(originator2)).thenReturn(details2);
|
||||
|
||||
// When
|
||||
enricher.enrich(loanAccountData);
|
||||
|
||||
// Then
|
||||
assertNotNull(loanAccountData.getOriginators());
|
||||
assertEquals(2, loanAccountData.getOriginators().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEnrich_NoOriginators() {
|
||||
// Given
|
||||
when(loanOriginatorMappingRepository.findByLoanIdWithOriginatorDetails(loanId)).thenReturn(Collections.emptyList());
|
||||
|
||||
// When
|
||||
enricher.enrich(loanAccountData);
|
||||
|
||||
// Then
|
||||
verify(loanOriginatorMappingRepository).findByLoanIdWithOriginatorDetails(loanId);
|
||||
verify(loanOriginatorAvroMapper, never()).toAvro(any());
|
||||
assertNull(loanAccountData.getOriginators());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEnrich_NullLoanId() {
|
||||
// Given
|
||||
loanAccountData.setId(null);
|
||||
|
||||
// When
|
||||
enricher.enrich(loanAccountData);
|
||||
|
||||
// Then
|
||||
verify(loanOriginatorMappingRepository, never()).findByLoanIdWithOriginatorDetails(any());
|
||||
assertNull(loanAccountData.getOriginators());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEnrich_NullData() {
|
||||
// When
|
||||
enricher.enrich(null);
|
||||
|
||||
// Then
|
||||
verify(loanOriginatorMappingRepository, never()).findByLoanIdWithOriginatorDetails(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEnrich_NullMappings() {
|
||||
// Given
|
||||
when(loanOriginatorMappingRepository.findByLoanIdWithOriginatorDetails(loanId)).thenReturn(null);
|
||||
|
||||
// When
|
||||
enricher.enrich(loanAccountData);
|
||||
|
||||
// Then
|
||||
verify(loanOriginatorMappingRepository).findByLoanIdWithOriginatorDetails(loanId);
|
||||
verify(loanOriginatorAvroMapper, never()).toAvro(any());
|
||||
assertNull(loanAccountData.getOriginators());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEnrich_NullOriginatorInMapping() {
|
||||
// Given
|
||||
final LoanOriginatorMapping mapping = mock(LoanOriginatorMapping.class);
|
||||
when(mapping.getOriginator()).thenReturn(null);
|
||||
final List<LoanOriginatorMapping> mappings = List.of(mapping);
|
||||
|
||||
when(loanOriginatorMappingRepository.findByLoanIdWithOriginatorDetails(loanId)).thenReturn(mappings);
|
||||
|
||||
// When
|
||||
enricher.enrich(loanAccountData);
|
||||
|
||||
// Then
|
||||
verify(loanOriginatorMappingRepository).findByLoanIdWithOriginatorDetails(loanId);
|
||||
verify(loanOriginatorAvroMapper, never()).toAvro(any());
|
||||
assertNull(loanAccountData.getOriginators());
|
||||
}
|
||||
|
||||
private LoanOriginator createTestOriginator(final Long id, final String externalId, final String name) {
|
||||
final LoanOriginator originator = LoanOriginator.create(new ExternalId(externalId), name, LoanOriginatorStatus.ACTIVE, null, null);
|
||||
originator.setId(id);
|
||||
return originator;
|
||||
}
|
||||
|
||||
private OriginatorDetailsV1 createOriginatorDetailsV1(final Long id, final String externalId, final String name) {
|
||||
return OriginatorDetailsV1.newBuilder().setId(id).setExternalId(externalId).setName(name).setStatus("ACTIVE")
|
||||
.setOriginatorType(null).setChannelType(null).build();
|
||||
}
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* 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.portfolio.loanorigination.enricher;
|
||||
|
||||
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 org.apache.fineract.avro.loan.v1.OriginatorDetailsV1;
|
||||
import org.apache.fineract.infrastructure.codes.domain.CodeValue;
|
||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginator;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginatorStatus;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class LoanOriginatorAvroMapperTest {
|
||||
|
||||
private LoanOriginatorAvroMapper mapper;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
mapper = new LoanOriginatorAvroMapper();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToAvro_WithAllFields() {
|
||||
// Given
|
||||
final CodeValue originatorType = createCodeValue(1L, "MERCHANT", "Merchant");
|
||||
final CodeValue channelType = createCodeValue(2L, "ONLINE", "Online");
|
||||
final LoanOriginator originator = LoanOriginator.create(new ExternalId("test-external-id"), "Test Originator",
|
||||
LoanOriginatorStatus.ACTIVE, originatorType, channelType);
|
||||
originator.setId(100L);
|
||||
|
||||
// When
|
||||
final OriginatorDetailsV1 result = mapper.toAvro(originator);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertEquals(100L, result.getId());
|
||||
assertEquals("test-external-id", result.getExternalId());
|
||||
assertEquals("Test Originator", result.getName());
|
||||
assertEquals("ACTIVE", result.getStatus());
|
||||
assertNotNull(result.getOriginatorType());
|
||||
assertEquals(1L, result.getOriginatorType().getId());
|
||||
assertEquals("MERCHANT", result.getOriginatorType().getName());
|
||||
assertNotNull(result.getChannelType());
|
||||
assertEquals(2L, result.getChannelType().getId());
|
||||
assertEquals("ONLINE", result.getChannelType().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToAvro_WithNullFields() {
|
||||
// Given
|
||||
final LoanOriginator originator = LoanOriginator.create(new ExternalId("test-external-id"), null, LoanOriginatorStatus.PENDING,
|
||||
null, null);
|
||||
originator.setId(200L);
|
||||
|
||||
// When
|
||||
final OriginatorDetailsV1 result = mapper.toAvro(originator);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertEquals(200L, result.getId());
|
||||
assertEquals("test-external-id", result.getExternalId());
|
||||
assertNull(result.getName());
|
||||
assertEquals("PENDING", result.getStatus());
|
||||
assertNull(result.getOriginatorType());
|
||||
assertNull(result.getChannelType());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToAvro_NullOriginator() {
|
||||
// When
|
||||
final OriginatorDetailsV1 result = mapper.toAvro(null);
|
||||
|
||||
// Then
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToAvro_NullExternalId() {
|
||||
// Given
|
||||
final LoanOriginator originator = LoanOriginator.create(null, "Test", LoanOriginatorStatus.ACTIVE, null, null);
|
||||
originator.setId(300L);
|
||||
|
||||
// When
|
||||
final OriginatorDetailsV1 result = mapper.toAvro(originator);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertEquals(300L, result.getId());
|
||||
assertNull(result.getExternalId());
|
||||
}
|
||||
|
||||
private CodeValue createCodeValue(final Long id, final String label, final String description) {
|
||||
final CodeValue codeValue = new CodeValue();
|
||||
codeValue.setId(id);
|
||||
codeValue.setLabel(label);
|
||||
codeValue.setDescription(description);
|
||||
codeValue.setPosition(1);
|
||||
codeValue.setActive(true);
|
||||
codeValue.setMandatory(false);
|
||||
return codeValue;
|
||||
}
|
||||
}
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
* 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.portfolio.loanorigination.enricher;
|
||||
|
||||
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.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1;
|
||||
import org.apache.fineract.avro.loan.v1.OriginatorDetailsV1;
|
||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginator;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginatorMapping;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginatorMappingRepository;
|
||||
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginatorStatus;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class LoanTransactionDataV1OriginatorEnricherTest {
|
||||
|
||||
@Mock
|
||||
private LoanOriginatorMappingRepository loanOriginatorMappingRepository;
|
||||
|
||||
@Mock
|
||||
private LoanOriginatorAvroMapper loanOriginatorAvroMapper;
|
||||
|
||||
@InjectMocks
|
||||
private LoanTransactionDataV1OriginatorEnricher enricher;
|
||||
|
||||
private LoanTransactionDataV1 loanTransactionData;
|
||||
private Long loanId;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
loanId = 1L;
|
||||
loanTransactionData = new LoanTransactionDataV1();
|
||||
loanTransactionData.setLoanId(loanId);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsDataTypeSupported() {
|
||||
assertTrue(enricher.isDataTypeSupported(LoanTransactionDataV1.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEnrich_WithOriginators() {
|
||||
// Given
|
||||
final LoanOriginator originator = createTestOriginator(1L, "test-originator-1", "Test Originator 1");
|
||||
final LoanOriginatorMapping mapping = LoanOriginatorMapping.create(loanId, originator);
|
||||
final List<LoanOriginatorMapping> mappings = List.of(mapping);
|
||||
|
||||
final OriginatorDetailsV1 originatorDetails = createOriginatorDetailsV1(1L, "test-originator-1", "Test Originator 1");
|
||||
|
||||
when(loanOriginatorMappingRepository.findByLoanIdWithOriginatorDetails(loanId)).thenReturn(mappings);
|
||||
when(loanOriginatorAvroMapper.toAvro(originator)).thenReturn(originatorDetails);
|
||||
|
||||
// When
|
||||
enricher.enrich(loanTransactionData);
|
||||
|
||||
// Then
|
||||
verify(loanOriginatorMappingRepository).findByLoanIdWithOriginatorDetails(loanId);
|
||||
verify(loanOriginatorAvroMapper).toAvro(originator);
|
||||
assertNotNull(loanTransactionData.getOriginators());
|
||||
assertEquals(1, loanTransactionData.getOriginators().size());
|
||||
assertEquals("test-originator-1", loanTransactionData.getOriginators().getFirst().getExternalId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEnrich_WithMultipleOriginators() {
|
||||
// Given
|
||||
final LoanOriginator originator1 = createTestOriginator(1L, "test-originator-1", "Test Originator 1");
|
||||
final LoanOriginator originator2 = createTestOriginator(2L, "test-originator-2", "Test Originator 2");
|
||||
final List<LoanOriginatorMapping> mappings = List.of(LoanOriginatorMapping.create(loanId, originator1),
|
||||
LoanOriginatorMapping.create(loanId, originator2));
|
||||
|
||||
final OriginatorDetailsV1 details1 = createOriginatorDetailsV1(1L, "test-originator-1", "Test Originator 1");
|
||||
final OriginatorDetailsV1 details2 = createOriginatorDetailsV1(2L, "test-originator-2", "Test Originator 2");
|
||||
|
||||
when(loanOriginatorMappingRepository.findByLoanIdWithOriginatorDetails(loanId)).thenReturn(mappings);
|
||||
when(loanOriginatorAvroMapper.toAvro(originator1)).thenReturn(details1);
|
||||
when(loanOriginatorAvroMapper.toAvro(originator2)).thenReturn(details2);
|
||||
|
||||
// When
|
||||
enricher.enrich(loanTransactionData);
|
||||
|
||||
// Then
|
||||
assertNotNull(loanTransactionData.getOriginators());
|
||||
assertEquals(2, loanTransactionData.getOriginators().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEnrich_NoOriginators() {
|
||||
// Given
|
||||
when(loanOriginatorMappingRepository.findByLoanIdWithOriginatorDetails(loanId)).thenReturn(Collections.emptyList());
|
||||
|
||||
// When
|
||||
enricher.enrich(loanTransactionData);
|
||||
|
||||
// Then
|
||||
verify(loanOriginatorMappingRepository).findByLoanIdWithOriginatorDetails(loanId);
|
||||
verify(loanOriginatorAvroMapper, never()).toAvro(any());
|
||||
assertNull(loanTransactionData.getOriginators());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEnrich_NullLoanId() {
|
||||
// Given
|
||||
loanTransactionData.setLoanId(null);
|
||||
|
||||
// When
|
||||
enricher.enrich(loanTransactionData);
|
||||
|
||||
// Then
|
||||
verify(loanOriginatorMappingRepository, never()).findByLoanIdWithOriginatorDetails(any());
|
||||
assertNull(loanTransactionData.getOriginators());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEnrich_NullData() {
|
||||
// When
|
||||
enricher.enrich(null);
|
||||
|
||||
// Then
|
||||
verify(loanOriginatorMappingRepository, never()).findByLoanIdWithOriginatorDetails(any());
|
||||
}
|
||||
|
||||
private LoanOriginator createTestOriginator(final Long id, final String externalId, final String name) {
|
||||
final LoanOriginator originator = LoanOriginator.create(new ExternalId(externalId), name, LoanOriginatorStatus.ACTIVE, null, null);
|
||||
originator.setId(id);
|
||||
return originator;
|
||||
}
|
||||
|
||||
private OriginatorDetailsV1 createOriginatorDetailsV1(final Long id, final String externalId, final String name) {
|
||||
return OriginatorDetailsV1.newBuilder().setId(id).setExternalId(externalId).setName(name).setStatus("ACTIVE")
|
||||
.setOriginatorType(null).setChannelType(null).build();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user