added batch file upload feature

This commit is contained in:
Prince
2026-06-20 02:33:37 +02:00
parent dcb917e899
commit 4d0e18c1a6
26 changed files with 2263 additions and 104 deletions

View File

@@ -0,0 +1,167 @@
package zw.qantra.tm.domain.services;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
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;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import zw.qantra.tm.domain.enums.CurrencyType;
import zw.qantra.tm.domain.enums.RequestType;
import zw.qantra.tm.domain.models.AdditionalData;
import zw.qantra.tm.domain.models.Currency;
import zw.qantra.tm.domain.models.Transaction;
import zw.qantra.tm.domain.repositories.AdditionalDataRepository;
import zw.qantra.tm.domain.repositories.TransactionRepository;
import zw.qantra.tm.exceptions.ApiException;
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class TransactionServiceTest {
@Mock
private TransactionRepository transactionRepository;
@Mock
private AdditionalDataService additionalDataService;
@Mock
private CurrencyService currencyService;
@Mock
private AdditionalDataRepository additionalDataRepository;
@InjectMocks
private TransactionService transactionService;
private Transaction transaction;
private final UUID txId = UUID.randomUUID();
@BeforeEach
void setUp() {
transaction = new Transaction();
transaction.setId(txId);
transaction.setUserId("user-1");
transaction.setAmount(new BigDecimal("100.00"));
transaction.setDebitCurrency(CurrencyType.USD);
transaction.setCreditCurrency(CurrencyType.ZWL);
lenient().when(additionalDataService.getAdditionalDataRepository()).thenReturn(additionalDataRepository);
}
@Test
@DisplayName("Should find transaction by ID")
void shouldFindById() {
when(transactionRepository.findById(txId)).thenReturn(Optional.of(transaction));
AdditionalData additionalData = new AdditionalData();
additionalData.setJsonString("[{\"key\":\"value\"}]");
when(additionalDataRepository.findByTransactionIdAndRequestType(
txId.toString(), RequestType.INTEGRATION))
.thenReturn(Optional.of(additionalData));
Transaction result = transactionService.findById(txId);
assertNotNull(result);
assertEquals(txId, result.getId());
assertNotNull(result.getAdditionalData());
}
@Test
@DisplayName("Should throw exception when transaction not found by ID")
void shouldThrowWhenNotFound() {
when(transactionRepository.findById(txId)).thenReturn(Optional.empty());
assertThrows(ApiException.class, () -> transactionService.findById(txId));
}
@Test
@DisplayName("Should find transaction without additional data gracefully")
void shouldFindByIdWithoutAdditionalData() {
when(transactionRepository.findById(txId)).thenReturn(Optional.of(transaction));
when(additionalDataRepository.findByTransactionIdAndRequestType(
txId.toString(), RequestType.INTEGRATION))
.thenThrow(new ApiException("Not found"));
Transaction result = transactionService.findById(txId);
assertNotNull(result);
assertNull(result.getAdditionalData());
}
@Test
@DisplayName("Should return paginated transactions")
void shouldFindAllPaginated() {
Specification<Transaction> spec = mock(Specification.class);
Pageable pageable = PageRequest.of(0, 10);
Page<Transaction> page = new PageImpl<>(List.of(transaction));
when(transactionRepository.findAll(spec, pageable)).thenReturn(page);
Page<Transaction> result = transactionService.findAll(spec, pageable);
assertEquals(1, result.getTotalElements());
assertEquals(txId, result.getContent().get(0).getId());
}
@Test
@DisplayName("Should calculate credit amount using bank rate")
void shouldCalculateCreditAmount() {
Currency currency = new Currency();
currency.setBankRate("15.0");
when(currencyService.findCurrencyByIsoCode("ZWL")).thenReturn(currency);
BigDecimal creditAmount = transactionService.calculateCreditAmount(transaction);
assertEquals(new BigDecimal("1500.0000"), creditAmount);
assertEquals(new BigDecimal("1500.0000"), transaction.getCreditAmount());
}
@Test
@DisplayName("Should return zero credit amount when credit currency is null")
void shouldReturnZeroWhenCreditCurrencyNull() {
transaction.setCreditCurrency(null);
BigDecimal result = transactionService.calculateCreditAmount(transaction);
assertEquals(BigDecimal.ZERO, result);
}
@Test
@DisplayName("Should reassign transactions from old user to new user")
void shouldReassignTransactions() {
List<Transaction> transactions = List.of(transaction);
when(transactionRepository.findAllByUserId("old-user")).thenReturn(transactions);
when(transactionRepository.save(any(Transaction.class))).thenReturn(transaction);
transactionService.reassignTransactions("old-user", "new-user");
assertEquals("new-user", transaction.getUserId());
verify(transactionRepository).save(transaction);
}
@Test
@DisplayName("Should save transaction")
void shouldSave() {
when(transactionRepository.save(transaction)).thenReturn(transaction);
Transaction result = transactionService.save(transaction);
assertNotNull(result);
verify(transactionRepository).save(transaction);
}
}