Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • xkollar3/online-banking-service
1 result
Show changes
Showing
with 783 additions and 142 deletions
package cz.muni.fi.obs.data.repository;
import cz.muni.fi.obs.data.dbo.ScheduledPayment;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.time.Instant;
import java.util.List;
@Repository
public interface ScheduledPaymentRepository extends JpaRepository<ScheduledPayment, String> {
@Query("SELECT p FROM ScheduledPayment p WHERE p.dayOfWeek = ?1 AND (p.validUntil is null OR p.validUntil > ?2)")
List<ScheduledPayment> findAllByDayOfWeek(Integer dayOfWeek, Instant now);
@Query("SELECT p FROM ScheduledPayment p WHERE p.dayOfMonth >= 28 AND (p.validUntil is null OR p.validUntil > ?1)")
List<ScheduledPayment> findForEndOfMonth(Instant now);
@Query("SELECT p FROM ScheduledPayment p WHERE p.dayOfMonth = ?1 AND (p.validUntil is null OR p.validUntil > ?2)")
List<ScheduledPayment> findAllByDayOfMonth(int dayOfMonth, Instant now);
@Query("SELECT p FROM ScheduledPayment p WHERE p.dayOfYear = ?1 AND (p.validUntil is null OR p.validUntil > ?2)")
List<ScheduledPayment> findAllByDayOfYear(int dayOfYear, Instant now);
}
package cz.muni.fi.obs.data.repository;
import java.util.List;
import cz.muni.fi.obs.data.dbo.TransactionDbo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import cz.muni.fi.obs.data.dbo.TransactionDbo;
import java.util.List;
@Repository
public interface TransactionRepository extends JpaRepository<TransactionDbo, String> {
List<TransactionDbo> findTransactionsDboByWithdrawsFrom_Id(String accountId);
List<TransactionDbo> findTransactionsDboByDepositsTo_Id(String accountId);
@Query("SELECT t FROM TransactionDbo t WHERE t.withdrawsFrom.id = :accountId OR t.depositsTo.id = :accountId")
......
package cz.muni.fi.obs.exceptions;
// fixme: add meaningful messages
public class ResourceNotFoundException extends RuntimeException {
private Object id;
private Class<?> resourceClass;
public ResourceNotFoundException() {
super();
}
......@@ -16,4 +22,9 @@ public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(Throwable cause) {
super(cause);
}
public ResourceNotFoundException(Class<?> resourceClass, Object resourceId) {
this.resourceClass = resourceClass;
this.id = resourceId;
}
}
package cz.muni.fi.obs.facade;
import cz.muni.fi.obs.api.TransactionCreateDto;
import cz.muni.fi.obs.data.dbo.ScheduledPayment;
import cz.muni.fi.obs.service.TransactionService;
import cz.muni.fi.obs.service.payment.ScheduledPaymentRetrievalService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Transactional
@Service
public class ScheduledPaymentExecutorFacade {
private static final Integer END_OF_MONTH_PAYMENT_DAY = 28;
private static final String SCHEDULER_NOTE = "Automatic payment.";
private final ScheduledPaymentRetrievalService retrievalService;
private final TransactionService transactionService;
@Autowired
public ScheduledPaymentExecutorFacade(ScheduledPaymentRetrievalService retrievalService,
TransactionService transactionService) {
this.retrievalService = retrievalService;
this.transactionService = transactionService;
}
@Scheduled(cron = "0 10 1 * * *")
public void executeWeekly() {
log.info("Executing weekly payments...");
executeReadyPayments(retrievalService.findForCurrentDayOfWeek());
log.info("Executed weekly payments...");
}
@Scheduled(cron = "0 20 1 * * *")
public void executeMonthly() {
log.info("Executing monthly payments...");
LocalDate date = LocalDate.now();
int today = date.getDayOfMonth();
int tommorrow = date.plusDays(1).getDayOfMonth();
List<ScheduledPayment> ready = new ArrayList<>();
// if today is >= 28 only execute payments if its last day of month
if (today >= END_OF_MONTH_PAYMENT_DAY) {
if (tommorrow < today) {
ready = retrievalService.findForEndOfMonth();
}
} else {
ready = retrievalService.findForCurrentDayOfMonth();
}
executeReadyPayments(ready);
log.info("Executed monthly payments...");
}
@Scheduled(cron = "0 30 1 * * *")
public void executeYearly() {
log.info("Executing yearly payments...");
executeReadyPayments(retrievalService.findForCurrentDayOfYear());
log.info("Executed yearly payments...");
}
private void executeReadyPayments(List<ScheduledPayment> ready) {
ready.forEach(payment -> {
TransactionCreateDto transactionCreateDto = new TransactionCreateDto(payment.getWithdrawsFrom().getAccountNumber(), payment.getDepositsTo().getAccountNumber(), payment.getAmount(),
SCHEDULER_NOTE, "");
transactionService.createTransaction(transactionCreateDto);
});
}
}
package cz.muni.fi.obs.facade;
import cz.muni.fi.obs.api.ScheduledPaymentCreateDto;
import cz.muni.fi.obs.api.ScheduledPaymentDto;
import java.time.Instant;
public interface ScheduledPaymentFacade {
ScheduledPaymentDto createPayment(ScheduledPaymentCreateDto createDto);
void disablePayment(String id, Instant disableTime);
void enablePayment(String id);
}
......@@ -34,9 +34,7 @@ public class TransactionManagementFacade {
}
public TransactionDbo createTransaction(TransactionCreateDto transaction) {
AccountDbo withdrawsFromAccount = getAccountByAccountNumber(transaction.withdrawsFromAccountNumber());
AccountDbo depositsToAccount = getAccountByAccountNumber(transaction.depositsToAccountNumber());
return transactionService.createTransaction(transaction, withdrawsFromAccount, depositsToAccount);
return transactionService.createTransaction(transaction);
}
public Page<TransactionDbo> viewTransactionHistory(String accountNumber, int pageNumber, int pageSize) {
......@@ -46,7 +44,7 @@ public class TransactionManagementFacade {
public BigDecimal checkAccountBalance(String accountNumber) {
AccountDbo account = getAccountByAccountNumber(accountNumber);
return transactionService.checkAccountBalance(account.getId());
return transactionService.calculateAccountBalance(account.getId());
}
public AccountDbo createAccount(AccountCreateDto accountCreateDto) {
......
package cz.muni.fi.obs.http;
import java.util.Optional;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import cz.muni.fi.obs.api.CurrencyExchangeRequest;
import cz.muni.fi.obs.api.CurrencyExchangeResult;
import cz.muni.fi.obs.config.FeignClientConfiguration.CurrencyServiceClientConfiguration;
import cz.muni.fi.obs.config.FeignClientConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.Optional;
@FeignClient(
name = "currency-service",
url = "${clients.currency-service.url}",
configuration = CurrencyServiceClientConfiguration.class,
configuration = FeignClientConfiguration.CurrencyServiceClientConfiguration.class,
fallback = CurrencyServiceClient.Fallback.class
)
public interface CurrencyServiceClient {
......
package cz.muni.fi.obs.mapper;
import cz.muni.fi.obs.api.ScheduledPaymentDto;
import cz.muni.fi.obs.data.dbo.ScheduledPayment;
import org.mapstruct.Mapper;
@Mapper
public interface ScheduledPaymentMapper {
ScheduledPaymentDto toDto(ScheduledPayment scheduledPayment);
}
package cz.muni.fi.obs.service;
import java.math.BigDecimal;
import java.util.Optional;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cz.muni.fi.obs.api.CurrencyExchangeRequest;
import cz.muni.fi.obs.api.CurrencyExchangeResult;
import cz.muni.fi.obs.api.TransactionCreateDto;
import cz.muni.fi.obs.data.dbo.AccountDbo;
import cz.muni.fi.obs.data.dbo.TransactionDbo;
import cz.muni.fi.obs.data.dbo.TransactionState;
import cz.muni.fi.obs.data.repository.AccountRepository;
import cz.muni.fi.obs.data.repository.TransactionRepository;
import cz.muni.fi.obs.exceptions.ResourceNotFoundException;
import cz.muni.fi.obs.http.CurrencyServiceClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Optional;
import java.util.UUID;
import static cz.muni.fi.obs.data.dbo.TransactionState.FAILED;
import static cz.muni.fi.obs.data.dbo.TransactionState.SUCCESSFUL;
@Slf4j
@Service
@Transactional
public class TransactionService {
private final TransactionRepository repository;
private final CurrencyServiceClient client;
private final AccountRepository accountRepository;
@Autowired
public TransactionService(TransactionRepository repository, CurrencyServiceClient client) {
public TransactionService(TransactionRepository repository, CurrencyServiceClient client, AccountRepository accountRepository) {
this.repository = repository;
this.client = client;
this.accountRepository = accountRepository;
}
@Transactional
public BigDecimal checkAccountBalance(String accountId) {
public BigDecimal calculateAccountBalance(String accountId) {
var withdraws = repository.findTransactionsDboByWithdrawsFrom_Id(accountId);
var deposits = repository.findTransactionsDboByDepositsTo_Id(accountId);
BigDecimal withdrawSum = withdraws.stream()
.filter(transactionDbo -> transactionDbo.getTransactionState().equals(SUCCESSFUL))
.map(TransactionDbo::getWithdrawAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal depositSum = deposits.stream()
.filter(transactionDbo -> transactionDbo.getTransactionState().equals(SUCCESSFUL))
.map(TransactionDbo::getDepositAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
......@@ -57,35 +65,39 @@ public class TransactionService {
return repository.findById(id);
}
@Transactional
public TransactionDbo createTransaction(TransactionCreateDto transaction, AccountDbo withdrawAccount,
AccountDbo depositAccount) {
public TransactionDbo createTransaction(TransactionCreateDto transaction) {
AccountDbo withdrawsFromAccount = accountRepository.findAccountDboByAccountNumber(transaction.withdrawsFromAccountNumber())
.orElseThrow(() -> new ResourceNotFoundException(AccountDbo.class, transaction.withdrawsFromAccountNumber()));
AccountDbo depositsToAccount = accountRepository.findAccountDboByAccountNumber(transaction.depositsToAccountNumber())
.orElseThrow(() -> new ResourceNotFoundException(AccountDbo.class, transaction.depositsToAccountNumber()));
CurrencyExchangeRequest request = CurrencyExchangeRequest.builder()
.from(transaction.withdrawsFromAccountNumber())
.to(transaction.depositsToAccountNumber())
.amount(transaction.depositAmount())
.amount(transaction.withdrawAmount())
.build();
CurrencyExchangeResult conversionRate = callCurrencyClient(request);
CurrencyExchangeResult exchangeResult = callCurrencyClient(request);
var transactionDbo = TransactionDbo.builder()
.id(UUID.randomUUID().toString())
.withdrawsFrom(withdrawAccount)
.withdrawsFrom(withdrawsFromAccount)
.note(transaction.note())
.depositsTo(depositAccount)
.depositAmount(transaction.depositAmount())
.depositsTo(depositsToAccount)
.depositAmount(exchangeResult.destAmount())
.withdrawAmount(transaction.withdrawAmount())
.variableSymbol(transaction.variableSymbol())
.conversionRate(conversionRate.exchangeRate())
.conversionRate(exchangeResult.exchangeRate())
.transactionState(computeTransactionState(withdrawsFromAccount.getId(), transaction.withdrawAmount()))
.build();
if (checkAccountBalance(withdrawAccount.getId()).compareTo(transaction.depositAmount()) < 0) {
return null;
}
return repository.save(transactionDbo);
}
private TransactionState computeTransactionState(String id, BigDecimal withdrawAmount) {
return calculateAccountBalance(id).compareTo(withdrawAmount) > 0 ? SUCCESSFUL : FAILED;
}
private CurrencyExchangeResult callCurrencyClient(CurrencyExchangeRequest request) {
return client.getCurrencyExchange(request)
.orElseThrow(() -> new ResourceNotFoundException("Currency exchange rate not found"));
......
package cz.muni.fi.obs.service.payment;
import cz.muni.fi.obs.data.dbo.ScheduledPayment;
import cz.muni.fi.obs.data.repository.ScheduledPaymentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.Instant;
import java.time.LocalDate;
import java.util.List;
@Service
public class ScheduledPaymentRetrievalService {
private final ScheduledPaymentRepository repository;
@Autowired
public ScheduledPaymentRetrievalService(ScheduledPaymentRepository repository) {
this.repository = repository;
}
public List<ScheduledPayment> findForCurrentDayOfWeek() {
return repository.findAllByDayOfWeek(LocalDate.now().getDayOfWeek().ordinal(), Instant.now());
}
public List<ScheduledPayment> findForEndOfMonth() {
return repository.findForEndOfMonth(Instant.now());
}
public List<ScheduledPayment> findForCurrentDayOfMonth() {
return repository.findAllByDayOfMonth(LocalDate.now().getDayOfMonth(), Instant.now());
}
public List<ScheduledPayment> findForCurrentDayOfYear() {
return repository.findAllByDayOfYear(Math.min(LocalDate.now().getDayOfYear(), 365), Instant.now());
}
}
package cz.muni.fi.obs.service.payment;
import cz.muni.fi.obs.api.ScheduledPaymentCreateDto;
import cz.muni.fi.obs.api.ScheduledPaymentDto;
import cz.muni.fi.obs.data.dbo.AccountDbo;
import cz.muni.fi.obs.data.dbo.PaymentFrequency;
import cz.muni.fi.obs.data.dbo.ScheduledPayment;
import cz.muni.fi.obs.data.repository.AccountRepository;
import cz.muni.fi.obs.data.repository.ScheduledPaymentRepository;
import cz.muni.fi.obs.exceptions.ResourceNotFoundException;
import cz.muni.fi.obs.facade.ScheduledPaymentFacade;
import cz.muni.fi.obs.mapper.ScheduledPaymentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.Instant;
import java.time.LocalDate;
@Service
@Transactional
public class ScheduledPaymentService implements ScheduledPaymentFacade {
private final ScheduledPaymentRepository scheduledPaymentRepository;
private final AccountRepository accountRepository;
private final ScheduledPaymentMapper mapper;
@Autowired
public ScheduledPaymentService(ScheduledPaymentRepository scheduledPaymentRepository,
AccountRepository accountRepository,
ScheduledPaymentMapper mapper) {
this.scheduledPaymentRepository = scheduledPaymentRepository;
this.accountRepository = accountRepository;
this.mapper = mapper;
}
@Override
public ScheduledPaymentDto createPayment(ScheduledPaymentCreateDto createDto) {
AccountDbo from = accountRepository.findById(createDto.withdrawsFromId())
.orElseThrow(() -> new ResourceNotFoundException(AccountDbo.class, createDto.withdrawsFromId()));
AccountDbo to = accountRepository.findById(createDto.depositsToId())
.orElseThrow(() -> new ResourceNotFoundException(AccountDbo.class, createDto.depositsToId()));
ScheduledPayment scheduledPayment = new ScheduledPayment();
scheduledPayment.setValidUntil(createDto.validUntil());
scheduledPayment.setWithdrawsFrom(from);
scheduledPayment.setDepositsTo(to);
setTiming(scheduledPayment, createDto.frequency(), createDto.executeDate());
return mapper.toDto(scheduledPaymentRepository.save(scheduledPayment));
}
@Override
public void disablePayment(String id, Instant disableTime) {
ScheduledPayment scheduledPayment = scheduledPaymentRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(
ScheduledPayment.class, id
));
scheduledPayment.setValidUntil(disableTime);
scheduledPaymentRepository.save(scheduledPayment);
}
@Override
public void enablePayment(String id) {
ScheduledPayment scheduledPayment = scheduledPaymentRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(
ScheduledPayment.class, id
));
scheduledPayment.setValidUntil(null);
scheduledPaymentRepository.save(scheduledPayment);
}
private void setTiming(ScheduledPayment scheduledPayment, PaymentFrequency frequency, LocalDate executeDate) {
switch (frequency) {
case WEEKLY -> {
scheduledPayment.setDayOfWeek(executeDate.getDayOfWeek().ordinal());
return;
}
case MONTHLY -> {
scheduledPayment.setDayOfMonth(executeDate.getDayOfMonth());
return;
}
case YEARLY -> {
scheduledPayment.setDayOfYear(Math.min(executeDate.getDayOfYear(), 365));
return;
}
}
}
}
CREATE TABLE scheduled_payment
(
id varchar(40) PRIMARY KEY,
amount numeric(38, 2) NOT NULL,
day_of_week int,
day_of_month int,
day_of_year int,
valid_until timestamp,
withdraws_from_id varchar(40) not null,
deposits_to_id varchar(40) not null,
constraint scheduled_payment_withdraws_from_FK foreign key (withdraws_from_id) references accounts (id),
constraint scheduled_payment_deposits_to_FK foreign key (deposits_to_id) references accounts (id)
);
CREATE INDEX day_of_week_IDX on scheduled_payment (day_of_week);
CREATE INDEX day_of_month_IDX on scheduled_payment (day_of_month);
CREATE INDEX day_of_year_IDX on scheduled_payment (day_of_year);
CREATE INDEX withdraws_from_id_IDX on scheduled_payment (withdraws_from_id);
CREATE INDEX deposits_to_IDX on scheduled_payment (deposits_to_id);
ALTER TABLE transactions
ADD COLUMN transaction_state varchar(255) NOT NULL;
\ No newline at end of file
......@@ -3,6 +3,7 @@ package cz.muni.fi.obs;
import cz.muni.fi.obs.api.TransactionCreateDto;
import cz.muni.fi.obs.data.dbo.AccountDbo;
import cz.muni.fi.obs.data.dbo.TransactionDbo;
import cz.muni.fi.obs.data.dbo.TransactionState;
import java.math.BigDecimal;
import java.util.Arrays;
......@@ -22,6 +23,7 @@ public class TestData {
.withdrawsFrom(withdrawAccount())
.depositAmount(BigDecimal.valueOf(250))
.variableSymbol("123")
.transactionState(TransactionState.SUCCESSFUL)
.build(),
TransactionDbo.builder()
.id("2")
......@@ -32,6 +34,7 @@ public class TestData {
.withdrawsFrom(withdrawAccount())
.depositAmount(BigDecimal.valueOf(2))
.variableSymbol("123")
.transactionState(TransactionState.SUCCESSFUL)
.build()
);
......@@ -45,6 +48,7 @@ public class TestData {
.withdrawsFrom(withdrawAccount())
.depositAmount(BigDecimal.valueOf(3001.5))
.variableSymbol("123")
.transactionState(TransactionState.SUCCESSFUL)
.build(),
TransactionDbo.builder()
......@@ -56,6 +60,7 @@ public class TestData {
.withdrawsFrom(withdrawAccount())
.depositAmount(BigDecimal.valueOf(44))
.variableSymbol("123")
.transactionState(TransactionState.SUCCESSFUL)
.build()
);
......@@ -64,7 +69,6 @@ public class TestData {
TestData.withdrawTransactions.getFirst().getWithdrawsFrom().getAccountNumber(),
TestData.withdrawTransactions.getFirst().getDepositsTo().getAccountNumber(),
TestData.withdrawTransactions.getFirst().getWithdrawAmount(),
TestData.withdrawTransactions.getFirst().getDepositAmount(),
TestData.withdrawTransactions.getFirst().getNote(),
TestData.withdrawTransactions.getFirst().getVariableSymbol()
);
......
package cz.muni.fi.obs.controller;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import com.fasterxml.jackson.core.type.TypeReference;
import cz.muni.fi.obs.TestData;
import cz.muni.fi.obs.api.TransactionCreateDto;
import cz.muni.fi.obs.controller.pagination.PagedResponse;
import cz.muni.fi.obs.data.dbo.TransactionDbo;
import cz.muni.fi.obs.facade.TransactionManagementFacade;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
......@@ -19,15 +15,17 @@ import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import util.JsonConvertor;
import com.fasterxml.jackson.core.type.TypeReference;
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import cz.muni.fi.obs.TestData;
import cz.muni.fi.obs.api.TransactionCreateDto;
import cz.muni.fi.obs.controller.pagination.PagedResponse;
import cz.muni.fi.obs.data.dbo.TransactionDbo;
import cz.muni.fi.obs.facade.TransactionManagementFacade;
import util.JsonConvertor;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(TransactionController.class)
class TransactionControllerTest {
......@@ -119,7 +117,6 @@ class TransactionControllerTest {
TestData.withdrawTransactions.getFirst().getWithdrawsFrom().getAccountNumber(),
TestData.withdrawTransactions.getFirst().getDepositsTo().getAccountNumber(),
TestData.withdrawTransactions.getFirst().getWithdrawAmount(),
TestData.withdrawTransactions.getFirst().getDepositAmount(),
TestData.withdrawTransactions.getFirst().getNote(),
TestData.withdrawTransactions.getFirst().getVariableSymbol()
);
......@@ -146,7 +143,6 @@ class TransactionControllerTest {
TestData.withdrawTransactions.getFirst().getWithdrawsFrom().getAccountNumber(),
null,
TestData.withdrawTransactions.getFirst().getWithdrawAmount(),
TestData.withdrawTransactions.getFirst().getDepositAmount(),
TestData.withdrawTransactions.getFirst().getNote(),
TestData.withdrawTransactions.getFirst().getVariableSymbol()
);
......
package cz.muni.fi.obs.repository;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_CLASS;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.BEFORE_TEST_CLASS;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Optional;
package cz.muni.fi.obs.data.repository;
import cz.muni.fi.obs.data.dbo.AccountDbo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.jdbc.Sql;
import cz.muni.fi.obs.data.dbo.AccountDbo;
import cz.muni.fi.obs.data.repository.AccountRepository;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_CLASS;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.BEFORE_TEST_CLASS;
@Sql(value = { "/initialize_db.sql" }, executionPhase = BEFORE_TEST_CLASS)
@Sql(value = { "/drop_all.sql" }, executionPhase = AFTER_TEST_CLASS)
......
package cz.muni.fi.obs.data.repository;
import cz.muni.fi.obs.data.dbo.AccountDbo;
import cz.muni.fi.obs.data.dbo.ScheduledPayment;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.ActiveProfiles;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@DataJpaTest
@ActiveProfiles("test")
public class ScheduledPaymentRepositoryTest {
@Autowired
private ScheduledPaymentRepository scheduledPaymentRepository;
@Autowired
private AccountRepository accountRepository;
private boolean setupDone = false;
@BeforeEach
public void setUp() {
if (setupDone) {
return;
}
AccountDbo accountDbo = new AccountDbo();
accountDbo.setId("123");
accountDbo.setAccountNumber("1233");
accountDbo.setCurrencyCode("CZK");
accountDbo.setCustomerId("mikoflosso");
accountDbo = accountRepository.save(accountDbo);
AccountDbo accountDbo1 = new AccountDbo();
accountDbo1.setId("1234");
accountDbo1.setAccountNumber("12356");
accountDbo1.setCurrencyCode("CZK");
accountDbo1.setCustomerId("ego");
accountDbo1 = accountRepository.save(accountDbo1);
BigDecimal amount = BigDecimal.valueOf(1000);
Instant past = Instant.now().minusSeconds(1000);
// ONCE A MONTH
ScheduledPayment scheduledPayment = new ScheduledPayment();
scheduledPayment.setDayOfMonth(1);
scheduledPayment.setAmount(amount);
scheduledPayment.setWithdrawsFrom(accountDbo);
scheduledPayment.setDepositsTo(accountDbo1);
scheduledPaymentRepository.save(scheduledPayment);
ScheduledPayment scheduledPayment1 = new ScheduledPayment();
scheduledPayment1.setDayOfMonth(1);
scheduledPayment1.setAmount(amount);
scheduledPayment1.setWithdrawsFrom(accountDbo);
scheduledPayment1.setDepositsTo(accountDbo1);
scheduledPayment1.setValidUntil(past);
scheduledPaymentRepository.save(scheduledPayment1);
// ONCE A WEEK
ScheduledPayment scheduledPayment2 = new ScheduledPayment();
scheduledPayment2.setDayOfWeek(1);
scheduledPayment2.setAmount(amount);
scheduledPayment2.setWithdrawsFrom(accountDbo);
scheduledPayment2.setDepositsTo(accountDbo1);
scheduledPaymentRepository.save(scheduledPayment2);
ScheduledPayment scheduledPayment3 = new ScheduledPayment();
scheduledPayment3.setDayOfWeek(1);
scheduledPayment3.setAmount(amount);
scheduledPayment3.setWithdrawsFrom(accountDbo);
scheduledPayment3.setDepositsTo(accountDbo1);
scheduledPayment3.setValidUntil(past);
scheduledPaymentRepository.save(scheduledPayment3);
// ONCE A YEAR
ScheduledPayment scheduledPayment4 = new ScheduledPayment();
scheduledPayment4.setDayOfYear(1);
scheduledPayment4.setAmount(amount);
scheduledPayment4.setWithdrawsFrom(accountDbo);
scheduledPayment4.setDepositsTo(accountDbo1);
scheduledPaymentRepository.save(scheduledPayment4);
ScheduledPayment scheduledPayment5 = new ScheduledPayment();
scheduledPayment5.setDayOfYear(1);
scheduledPayment5.setAmount(amount);
scheduledPayment5.setWithdrawsFrom(accountDbo);
scheduledPayment5.setDepositsTo(accountDbo1);
scheduledPayment5.setValidUntil(past);
scheduledPaymentRepository.save(scheduledPayment5);
// END OF MONTH
ScheduledPayment scheduledPayment6 = new ScheduledPayment();
scheduledPayment6.setDayOfMonth(30);
scheduledPayment6.setAmount(amount);
scheduledPayment6.setWithdrawsFrom(accountDbo);
scheduledPayment6.setDepositsTo(accountDbo1);
scheduledPaymentRepository.save(scheduledPayment6);
ScheduledPayment scheduledPayment7 = new ScheduledPayment();
scheduledPayment7.setDayOfWeek(30);
scheduledPayment7.setAmount(amount);
scheduledPayment7.setWithdrawsFrom(accountDbo);
scheduledPayment7.setDepositsTo(accountDbo1);
scheduledPayment7.setValidUntil(past);
scheduledPaymentRepository.save(scheduledPayment7);
setupDone = true;
}
@Test
public void findAllByDayOfWeek_oneTransactionExists_findsCorrectTransaction() {
List<ScheduledPayment> allByDayOfWeek =
scheduledPaymentRepository.findAllByDayOfWeek(1, Instant.now());
assertThat(allByDayOfWeek.size()).isEqualTo(1);
assertThat(allByDayOfWeek.getFirst().getValidUntil()).isNull();
}
@Test
public void findForEndOfMonth_oneTransactionExists_findsCorrectTransaction() {
List<ScheduledPayment> endOfMonth =
scheduledPaymentRepository.findForEndOfMonth(Instant.now());
assertThat(endOfMonth.size()).isEqualTo(1);
assertThat(endOfMonth.getFirst().getValidUntil()).isNull();
}
@Test
public void findAllByDayOfMonth_oneTransactionExists_findsCorrectTransaction() {
List<ScheduledPayment> dayOfMonth =
scheduledPaymentRepository.findForEndOfMonth(Instant.now());
assertThat(dayOfMonth.size()).isEqualTo(1);
assertThat(dayOfMonth.getFirst().getValidUntil()).isNull();
}
@Test
public void findAllByDayOfYear_oneTransactionExists_findsCorrectTransaction() {
List<ScheduledPayment> dayOfMonth =
scheduledPaymentRepository.findAllByDayOfYear(1, Instant.now());
assertThat(dayOfMonth.size()).isEqualTo(1);
assertThat(dayOfMonth.getFirst().getValidUntil()).isNull();
}
}
\ No newline at end of file
package cz.muni.fi.obs.repository;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_CLASS;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.BEFORE_TEST_CLASS;
import java.math.BigDecimal;
import java.util.List;
package cz.muni.fi.obs.data.repository;
import cz.muni.fi.obs.data.dbo.AccountDbo;
import cz.muni.fi.obs.data.dbo.TransactionDbo;
import cz.muni.fi.obs.data.dbo.TransactionState;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
......@@ -17,9 +12,13 @@ import org.springframework.data.domain.Pageable;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.jdbc.Sql;
import cz.muni.fi.obs.data.dbo.AccountDbo;
import cz.muni.fi.obs.data.dbo.TransactionDbo;
import cz.muni.fi.obs.data.repository.TransactionRepository;
import java.math.BigDecimal;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_CLASS;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.BEFORE_TEST_CLASS;
@Sql(value = { "/initialize_db.sql" }, executionPhase = BEFORE_TEST_CLASS)
@Sql(value = { "/drop_all.sql" }, executionPhase = AFTER_TEST_CLASS)
......@@ -32,7 +31,7 @@ public class TransactionRepositoryTest {
@Test
public void findTransactionsByWithdrawsFromId_transactionsFound_returnsTransactions() {
List<TransactionDbo> transactions = transactionRepository.findTransactionsDboByWithdrawsFrom_Id("1");
List<TransactionDbo> transactions = transactionRepository.findTransactionsDboByWithdrawsFrom_Id("1");
assertThat(transactions)
.hasSize(2)
......@@ -44,7 +43,7 @@ public class TransactionRepositoryTest {
insertTransaction();
List<TransactionDbo> transactionsAfterSaving = transactionRepository
.findTransactionsDboByWithdrawsFrom_Id("1");
.findTransactionsDboByWithdrawsFrom_Id("1");
assertThat(transactionsAfterSaving)
.hasSize(3)
......@@ -59,14 +58,14 @@ public class TransactionRepositoryTest {
@Test
public void findTransactionsByWithdrawsFromId_transactionsNotFound_returnsEmptyList() {
List<TransactionDbo> transactions = transactionRepository.findTransactionsDboByWithdrawsFrom_Id("non-existing");
List<TransactionDbo> transactions = transactionRepository.findTransactionsDboByWithdrawsFrom_Id("non-existing");
assertThat(transactions).hasSize(0);
}
@Test
public void findTransactionsByDepositsToId_transactionsFound_returnsTransactions() {
List<TransactionDbo> transactions = transactionRepository.findTransactionsDboByDepositsTo_Id("2");
List<TransactionDbo> transactions = transactionRepository.findTransactionsDboByDepositsTo_Id("2");
assertThat(transactions)
.hasSize(2)
......@@ -78,7 +77,7 @@ public class TransactionRepositoryTest {
insertTransaction();
List<TransactionDbo> transactionsAfterSaving = transactionRepository
.findTransactionsDboByDepositsTo_Id("2");
.findTransactionsDboByDepositsTo_Id("2");
assertThat(transactionsAfterSaving)
.hasSize(3)
......@@ -94,7 +93,7 @@ public class TransactionRepositoryTest {
@Test
public void findTransactionsByDepositsToId_transactionsNotFound_returnsEmptyList() {
List<TransactionDbo> transactions = transactionRepository
.findTransactionsDboByDepositsTo_Id("non-existing");
.findTransactionsDboByDepositsTo_Id("non-existing");
assertThat(transactions).hasSize(0);
}
......@@ -142,6 +141,7 @@ public class TransactionRepositoryTest {
.conversionRate(1.0)
.note("note-10")
.variableSymbol("1010")
.transactionState(TransactionState.SUCCESSFUL)
.build();
transactionRepository.save(transactionDbo);
......
package cz.muni.fi.obs.facade;
import cz.muni.fi.obs.api.CurrencyExchangeRequest;
import cz.muni.fi.obs.api.CurrencyExchangeResult;
import cz.muni.fi.obs.data.dbo.AccountDbo;
import cz.muni.fi.obs.data.dbo.ScheduledPayment;
import cz.muni.fi.obs.data.dbo.TransactionDbo;
import cz.muni.fi.obs.data.dbo.TransactionState;
import cz.muni.fi.obs.data.repository.AccountRepository;
import cz.muni.fi.obs.data.repository.ScheduledPaymentRepository;
import cz.muni.fi.obs.data.repository.TransactionRepository;
import cz.muni.fi.obs.http.CurrencyServiceClient;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.ActiveProfiles;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@SpringBootTest
@ActiveProfiles("test")
public class ScheduledPaymentExecutorFacadeTest {
@Autowired
private ScheduledPaymentExecutorFacade executorFacade;
@Autowired
private ScheduledPaymentRepository scheduledPaymentRepository;
@Autowired
private TransactionRepository transactionRepository;
@Autowired
private AccountRepository accountRepository;
@MockBean
private CurrencyServiceClient client;
private static final String SCHEDULER_NOTE = "Automatic payment.";
@BeforeEach
public void setUp() {
when(client.getCurrencyExchange(any(CurrencyExchangeRequest.class)))
.thenReturn(Optional.of(new CurrencyExchangeResult("CZK",
"CZK",
1d,
BigDecimal.valueOf(1000),
BigDecimal.valueOf(1000))));
if (scheduledPaymentRepository.count() > 0) {
return;
}
AccountDbo accountDbo = new AccountDbo();
accountDbo.setId("123");
accountDbo.setAccountNumber("1233");
accountDbo.setCurrencyCode("CZK");
accountDbo.setCustomerId("mikoflosso");
accountDbo = accountRepository.save(accountDbo);
AccountDbo accountDbo1 = new AccountDbo();
accountDbo1.setId("1234");
accountDbo1.setAccountNumber("12356");
accountDbo1.setCurrencyCode("CZK");
accountDbo1.setCustomerId("ego");
accountDbo1 = accountRepository.save(accountDbo1);
BigDecimal amount = BigDecimal.valueOf(1000);
Instant past = Instant.now().minusSeconds(1000);
// ONCE A MONTH
ScheduledPayment scheduledPayment = new ScheduledPayment();
scheduledPayment.setDayOfMonth(LocalDate.now().getDayOfMonth());
scheduledPayment.setAmount(amount);
scheduledPayment.setWithdrawsFrom(accountDbo);
scheduledPayment.setDepositsTo(accountDbo1);
scheduledPaymentRepository.save(scheduledPayment);
ScheduledPayment scheduledPayment1 = new ScheduledPayment();
scheduledPayment1.setDayOfMonth(LocalDate.now().getDayOfMonth());
scheduledPayment1.setAmount(amount);
scheduledPayment1.setWithdrawsFrom(accountDbo);
scheduledPayment1.setDepositsTo(accountDbo1);
scheduledPayment1.setValidUntil(past);
scheduledPaymentRepository.save(scheduledPayment1);
// ONCE A WEEK
ScheduledPayment scheduledPayment2 = new ScheduledPayment();
scheduledPayment2.setDayOfWeek(LocalDate.now().getDayOfWeek().ordinal());
scheduledPayment2.setAmount(amount);
scheduledPayment2.setWithdrawsFrom(accountDbo);
scheduledPayment2.setDepositsTo(accountDbo1);
scheduledPaymentRepository.save(scheduledPayment2);
ScheduledPayment scheduledPayment3 = new ScheduledPayment();
scheduledPayment3.setDayOfWeek(LocalDate.now().getDayOfWeek().ordinal());
scheduledPayment3.setAmount(amount);
scheduledPayment3.setWithdrawsFrom(accountDbo);
scheduledPayment3.setDepositsTo(accountDbo1);
scheduledPayment3.setValidUntil(past);
scheduledPaymentRepository.save(scheduledPayment3);
// ONCE A YEAR
ScheduledPayment scheduledPayment4 = new ScheduledPayment();
scheduledPayment4.setDayOfYear(LocalDate.now().getDayOfYear());
scheduledPayment4.setAmount(amount);
scheduledPayment4.setWithdrawsFrom(accountDbo);
scheduledPayment4.setDepositsTo(accountDbo1);
scheduledPaymentRepository.save(scheduledPayment4);
ScheduledPayment scheduledPayment5 = new ScheduledPayment();
scheduledPayment5.setDayOfYear(LocalDate.now().getDayOfYear());
scheduledPayment5.setAmount(amount);
scheduledPayment5.setWithdrawsFrom(accountDbo);
scheduledPayment5.setDepositsTo(accountDbo1);
scheduledPayment5.setValidUntil(past);
scheduledPaymentRepository.save(scheduledPayment5);
}
@AfterEach
public void cleanTransactions() {
transactionRepository.deleteAll();
}
@Test
public void executeWeekly_weeklyPaymentsExistForToday_paymentsAreExecuted() {
executorFacade.executeWeekly();
List<TransactionDbo> transactions = transactionRepository.findAll();
assertThat(transactions.size()).isEqualTo(1);
TransactionDbo first = transactions.getFirst();
assertThat(first.getWithdrawsFrom().getId()).isEqualTo("123");
assertThat(first.getDepositsTo().getId()).isEqualTo("1234");
assertThat(first.getNote()).isEqualTo(SCHEDULER_NOTE);
assertThat(first.getTransactionState()).isEqualTo(TransactionState.FAILED);
}
@Test
public void executeMonthly_monthlyPaymentsExistForToday_paymentsAreExecuted() {
executorFacade.executeMonthly();
List<TransactionDbo> transactions = transactionRepository.findAll();
assertThat(transactions.size()).isEqualTo(1);
TransactionDbo first = transactions.getFirst();
assertThat(first.getWithdrawsFrom().getId()).isEqualTo("123");
assertThat(first.getDepositsTo().getId()).isEqualTo("1234");
assertThat(first.getNote()).isEqualTo(SCHEDULER_NOTE);
assertThat(first.getTransactionState()).isEqualTo(TransactionState.FAILED);
}
@Test
public void executeYearly_yearlyPaymentsExistForToday_paymentsAreExecuted() {
executorFacade.executeYearly();
List<TransactionDbo> transactions = transactionRepository.findAll();
assertThat(transactions.size()).isEqualTo(1);
TransactionDbo first = transactions.getFirst();
assertThat(first.getWithdrawsFrom().getId()).isEqualTo("123");
assertThat(first.getDepositsTo().getId()).isEqualTo("1234");
assertThat(first.getNote()).isEqualTo(SCHEDULER_NOTE);
assertThat(first.getTransactionState()).isEqualTo(TransactionState.FAILED);
}
}
\ No newline at end of file
package cz.muni.fi.obs.facade;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.math.BigDecimal;
import java.util.Optional;
import cz.muni.fi.obs.TestData;
import cz.muni.fi.obs.api.AccountCreateDto;
import cz.muni.fi.obs.api.TransactionCreateDto;
import cz.muni.fi.obs.data.dbo.AccountDbo;
import cz.muni.fi.obs.data.dbo.TransactionDbo;
import cz.muni.fi.obs.service.AccountService;
import cz.muni.fi.obs.service.TransactionService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
......@@ -18,13 +16,13 @@ import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import cz.muni.fi.obs.TestData;
import cz.muni.fi.obs.api.AccountCreateDto;
import cz.muni.fi.obs.api.TransactionCreateDto;
import cz.muni.fi.obs.data.dbo.AccountDbo;
import cz.muni.fi.obs.data.dbo.TransactionDbo;
import cz.muni.fi.obs.service.AccountService;
import cz.muni.fi.obs.service.TransactionService;
import java.math.BigDecimal;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TransactionManagementFacadeTest {
......@@ -55,16 +53,12 @@ class TransactionManagementFacadeTest {
TestData.withdrawTransactions.getFirst().getWithdrawsFrom().getAccountNumber(),
TestData.withdrawTransactions.getFirst().getDepositsTo().getAccountNumber(),
TestData.withdrawTransactions.getFirst().getWithdrawAmount(),
TestData.withdrawTransactions.getFirst().getDepositAmount(),
TestData.withdrawTransactions.getFirst().getNote(),
TestData.withdrawTransactions.getFirst().getVariableSymbol()
);
AccountDbo emptyAccount = new AccountDbo();
when(accountService.findAccountByAccountNumber(any())).thenReturn(Optional.of(emptyAccount));
transactionManagementFacade.createTransaction(transactionCreateDto);
Mockito.verify(transactionService).createTransaction(transactionCreateDto, emptyAccount, emptyAccount);
Mockito.verify(transactionService).createTransaction(transactionCreateDto);
}
@Test
......@@ -85,7 +79,7 @@ class TransactionManagementFacadeTest {
@Test
public void checkAccountBalance_returnsBalance() {
when(transactionService.checkAccountBalance(TestData.accountId)).thenReturn(BigDecimal.valueOf(42));
when(transactionService.calculateAccountBalance(TestData.accountId)).thenReturn(BigDecimal.valueOf(42));
when(accountService.findAccountByAccountNumber("1234567890"))
.thenReturn(Optional.of(AccountDbo.builder()
.id(TestData.accountId)
......
package cz.muni.fi.obs.service;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import cz.muni.fi.obs.TestData;
import cz.muni.fi.obs.api.CurrencyExchangeResult;
import cz.muni.fi.obs.data.dbo.AccountDbo;
import cz.muni.fi.obs.data.dbo.TransactionDbo;
import cz.muni.fi.obs.data.repository.AccountRepository;
import cz.muni.fi.obs.data.repository.TransactionRepository;
import cz.muni.fi.obs.http.CurrencyServiceClient;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
......@@ -19,13 +16,13 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import cz.muni.fi.obs.TestData;
import cz.muni.fi.obs.api.CurrencyExchangeResult;
import cz.muni.fi.obs.api.TransactionCreateDto;
import cz.muni.fi.obs.data.dbo.AccountDbo;
import cz.muni.fi.obs.data.dbo.TransactionDbo;
import cz.muni.fi.obs.data.repository.TransactionRepository;
import cz.muni.fi.obs.http.CurrencyServiceClient;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class TransactionServiceTest {
......@@ -36,45 +33,48 @@ class TransactionServiceTest {
@Mock
CurrencyServiceClient client;
@Mock
AccountRepository accountRepository;
@InjectMocks
TransactionService transactionService;
@Test
public void checkAccountBalance_noTransactions_CalculatesCorrectly() {
when(repository.findTransactionsDboByWithdrawsFrom_Id(TestData.accountId)).thenReturn(Collections.emptyList());
when(repository.findTransactionsDboByDepositsTo_Id(TestData.accountId)).thenReturn(Collections.emptyList());
BigDecimal balance = transactionService.checkAccountBalance(TestData.accountId);
when(repository.findTransactionsDboByWithdrawsFrom_Id(TestData.accountId)).thenReturn(Collections.emptyList());
when(repository.findTransactionsDboByDepositsTo_Id(TestData.accountId)).thenReturn(Collections.emptyList());
BigDecimal balance = transactionService.calculateAccountBalance(TestData.accountId);
assertThat(balance).isEqualTo(BigDecimal.valueOf(0));
}
@Test
public void checkAccountBalance_singleWithdraw_calculatesCorrectly() {
when(repository.findTransactionsDboByWithdrawsFrom_Id(TestData.accountId)).thenReturn(
when(repository.findTransactionsDboByWithdrawsFrom_Id(TestData.accountId)).thenReturn(
List.of(TestData.withdrawTransactions.getFirst()));
when(repository.findTransactionsDboByDepositsTo_Id(TestData.accountId)).thenReturn(Collections.emptyList());
BigDecimal balance = transactionService.checkAccountBalance(TestData.accountId);
when(repository.findTransactionsDboByDepositsTo_Id(TestData.accountId)).thenReturn(Collections.emptyList());
BigDecimal balance = transactionService.calculateAccountBalance(TestData.accountId);
assertThat(balance).isEqualTo(BigDecimal.valueOf(-1000));
}
@Test
public void checkAccountBalance_singleDeposit_calculatesCorrectly() {
when(repository.findTransactionsDboByWithdrawsFrom_Id(TestData.accountId)).thenReturn(Collections.emptyList());
when(repository.findTransactionsDboByDepositsTo_Id(TestData.accountId)).thenReturn(
when(repository.findTransactionsDboByWithdrawsFrom_Id(TestData.accountId)).thenReturn(Collections.emptyList());
when(repository.findTransactionsDboByDepositsTo_Id(TestData.accountId)).thenReturn(
List.of(TestData.depositTransactions.getFirst()));
BigDecimal balance = transactionService.checkAccountBalance(TestData.accountId);
BigDecimal balance = transactionService.calculateAccountBalance(TestData.accountId);
assertThat(balance).isEqualTo(BigDecimal.valueOf(3001.5));
}
@Test
public void checkAccountBalance_multipleTransactions_calculatesCorrectly() {
when(repository.findTransactionsDboByWithdrawsFrom_Id(TestData.accountId)).thenReturn(
when(repository.findTransactionsDboByWithdrawsFrom_Id(TestData.accountId)).thenReturn(
TestData.withdrawTransactions);
when(repository.findTransactionsDboByDepositsTo_Id(TestData.accountId)).thenReturn(
when(repository.findTransactionsDboByDepositsTo_Id(TestData.accountId)).thenReturn(
TestData.depositTransactions);
BigDecimal balance = transactionService.checkAccountBalance(TestData.accountId);
BigDecimal balance = transactionService.calculateAccountBalance(TestData.accountId);
assertThat(balance).isEqualTo(BigDecimal.valueOf(2043.5));
}
......@@ -112,12 +112,12 @@ class TransactionServiceTest {
.symbolTo("EUR").build();
when(client.getCurrencyExchange(any())).thenReturn(Optional.of(exchangeResult));
when(repository.findTransactionsDboByWithdrawsFrom_Id(any())).thenReturn(Collections.emptyList());
when(repository.findTransactionsDboByDepositsTo_Id(any())).thenReturn(TestData.depositTransactions);
when(repository.findTransactionsDboByWithdrawsFrom_Id(any())).thenReturn(Collections.emptyList());
when(repository.findTransactionsDboByDepositsTo_Id(any())).thenReturn(TestData.depositTransactions);
when(repository.save(any())).thenReturn(TestData.withdrawTransactions.getFirst());
when(accountRepository.findAccountDboByAccountNumber(any())).thenReturn(Optional.of(new AccountDbo()));
TransactionDbo createdTransaction = transactionService.createTransaction(TestData.transactionCreateDto(),
TestData.withdrawAccount(), TestData.depositAccount());
TransactionDbo createdTransaction = transactionService.createTransaction(TestData.transactionCreateDto());
verify(repository).save(any());
assertThat(createdTransaction).isEqualTo(TestData.withdrawTransactions.getFirst());
......