Skip to content

Commit

Permalink
Implemented all business logic and all test, closes #6 Closes #4
Browse files Browse the repository at this point in the history
  • Loading branch information
mohamed-taman committed Sep 7, 2020
1 parent 5ba5815 commit d1b2e35
Show file tree
Hide file tree
Showing 21 changed files with 833 additions and 170 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
*/
public record CustomerAggregate(
@JsonProperty("id") int id,
@JsonProperty("firstName") String firstName,
@JsonProperty("lastName")String lastName,
@JsonProperty("name") String firstName,
@JsonProperty("Surname")String lastName,
@JsonProperty("balance") BigDecimal balance,
@JsonProperty("accounts") List<Account> accounts) {
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
package org.siriusxi.blueharvest.bank.common.api.dto;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

import java.math.BigDecimal;

@Data
@AllArgsConstructor
@RequiredArgsConstructor
public class AccountDTO {

private int customerId;
@NonNull
private BigDecimal initialCredit;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.siriusxi.blueharvest.bank.common.exception;

public class InvalidInputException extends RuntimeException {

public InvalidInputException() {}

public InvalidInputException(String message) {
super(message);
}

public InvalidInputException(String message, Throwable cause) {
super(message, cause);
}

public InvalidInputException(Throwable cause) {
super(cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.siriusxi.blueharvest.bank.common.exception;

public class NotFoundException extends RuntimeException {

public NotFoundException() {}

public NotFoundException(String message) {
super(message);
}

public NotFoundException(String message, Throwable cause) {
super(message, cause);
}

public NotFoundException(Throwable cause) {
super(cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ public AccountController(AccountService accountService) {
this.accountService = accountService;
}

@GetMapping(value = "accounts", produces = APPLICATION_JSON_VALUE)
@GetMapping(
value = "accounts",
produces = APPLICATION_JSON_VALUE)
public List<Account> getAccounts(@RequestParam("customerId") int customerId) {
return accountService.getAccounts(customerId);
}
Expand All @@ -33,8 +35,8 @@ public List<Account> getAccounts(@RequestParam("customerId") int customerId) {
value = "/accounts",
consumes = APPLICATION_JSON_VALUE)
public void createAccount(@RequestBody AccountDTO account) {
accountService.createAccount(new AccountEntity(account.getCustomerId(),
account.getInitialCredit()));
log.debug("createAccount: creates a new account {} for CustomerId: {}", account.toString());
accountService.createAccount(
new AccountEntity(account.getCustomerId(), account.getInitialCredit()));
log.debug("createAccount: creates a new account {}", account.toString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface AccountRepository extends CrudRepository<AccountEntity, Integer> {

Iterable<AccountEntity> findByCustomerId(int customerId);
List<AccountEntity> findByCustomerId(int customerId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,82 @@

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

/**
* <code>AccountService</code> class is a service layer in Account Microservice, that hold all business logic
* for Harvest
* Bank Accounts.
*
* @author Mohamed Taman
* @version 0.5
* @since Harvest beta v0.1
*/
@Service
@Log4j2
public class AccountService {

private final AccountRepository accountRepository;
private final TransactionIntegration transactionIntegration;
private final AccountRepository accountRepository;
private final TransactionIntegration transactionIntegration;

@Autowired
public AccountService(
AccountRepository accountRepository, TransactionIntegration transactionIntegration) {
this.accountRepository = accountRepository;
this.transactionIntegration = transactionIntegration;
}

@Autowired
public AccountService(AccountRepository accountRepository,
TransactionIntegration transactionIntegration) {
this.accountRepository = accountRepository;
this.transactionIntegration = transactionIntegration;
}
/**
* This method <code>getAccounts()<code/> return the accounts information with related
* transactions.
*
* @param customerId customer id
* @return List&lt;Account&gt; accounts and related transactions information.
* @since Harvest beta v0.1
*/
public List<Account> getAccounts(int customerId) {

public List<Account> getAccounts(int customerId) {
return StreamSupport
.stream(accountRepository.findByCustomerId(customerId).spliterator(),
false)
.map(entity -> new Account(customerId,entity.getBalance(), entity.getType()
,transactionIntegration.getAccountTransactions(entity.getId())))
.collect(Collectors.toList());
}
log.trace("Calling - getAccounts -> Getting all accounts for customer ID {}", customerId);

var accounts =
accountRepository.findByCustomerId(customerId).stream()
.map(
entity ->
new Account(
customerId,
entity.getBalance(),
entity.getType(),
transactionIntegration.getAccountTransactions(entity.getId())))
.collect(Collectors.toList());

log.trace("Returning - getAccounts -> With {} accounts", accounts.size());

public void createAccount(AccountEntity entity) {
accountRepository.save(entity);
transactionIntegration.createTransaction(new TransactionDTO(entity.getId(),
entity.getBalance()));
log.debug("Account created with ID -----> {}", entity.getId());
return accounts;
}

/**
* This method <code>createAccount()</code> is responsible to create customer accounts with the
* following logic:
*
* <ul>
* <li>Once the endpoint is called, a new account will be opened connected to the user whose ID
* is customerID.
* <li>Also, if initialCredit is not 0, a transaction will be sent to the new account.
* </ul>
*
* @param entity is the account to save.
* @since Harvest beta v0.1
*/
public void createAccount(AccountEntity entity) {
log.trace("Calling - createAccount -> to save account {}", entity);
accountRepository.save(entity);

if (entity.getBalance().doubleValue() > 0.0) {
transactionIntegration.createTransaction(
new TransactionDTO(entity.getId(), entity.getBalance()));

log.debug("New account transaction is created for account {}", entity.getId());
}

log.trace("Returning - createAccount -> account {} saved successfully", entity);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package org.siriusxi.blueharvest.bank.as;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.siriusxi.blueharvest.bank.as.api.AccountController;
import org.siriusxi.blueharvest.bank.as.service.AccountService;
import org.siriusxi.blueharvest.bank.common.api.composite.account.Account;
import org.siriusxi.blueharvest.bank.common.api.composite.trx.Transaction;
import org.siriusxi.blueharvest.bank.common.api.dto.AccountDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

import java.math.BigDecimal;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.hasSize;
import static org.mockito.BDDMockito.given;
import static org.siriusxi.blueharvest.bank.common.api.composite.account.AccountType.CURRENT;
import static org.siriusxi.blueharvest.bank.common.api.composite.trx.TransactionType.CREDIT;
import static org.siriusxi.blueharvest.bank.util.JsonUtilities.toJson;
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.*;

@WebMvcTest(AccountController.class)
class AccountControllerLayerTests {

@Autowired
private MockMvc mvc;

@MockBean
private AccountService accountService;

@BeforeEach
void setup() {
// Given
given(accountService.getAccounts(1))
.willReturn(
List.of(
new Account(
1,
new BigDecimal("1.0"),
CURRENT,
List.of(new Transaction(1, CREDIT, new BigDecimal("1.0"))))));
}

@Test
void whenInitialCreditGreaterThanZero_thenCreateAccountAndTransaction() throws Exception {

// When
mvc.perform(
post("/bank/api/v1/accounts")
.contentType(MediaType.APPLICATION_JSON)
.content(toJson(new AccountDTO(1, new BigDecimal("1.0")))))
.andExpect(status().isOk());

var accounts = accountService.getAccounts(1);

// Then
assertThat(accounts.get(0).balance()).isEqualTo(new BigDecimal("1.0"));

assertThat(accounts.get(0).type()).isEqualTo(CURRENT);

assertThat(accounts.get(0).transactions()).isNotNull();
assertThat(accounts.get(0).transactions().size()).isEqualTo(1);
}

@Test
void getAccountsByCustomerId_thenReturnAccountsAndTransactionsJsonArray() throws Exception {

// When
mvc.perform(get("/bank/api/v1/accounts?customerId=1")
.contentType(MediaType.APPLICATION_JSON))
// Then
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$", hasSize(1)))
.andExpect(jsonPath("$[0].balance", is(1.0)))
.andExpect(jsonPath("$[0].customerId", is(1)))
.andExpect(jsonPath("$[0].type", is("CURRENT")))
.andExpect(jsonPath("$[0].transactions", hasSize(1)))
.andExpect(jsonPath("$[0].transactions[0].accountId", is(1)))
.andExpect(jsonPath("$[0].transactions[0].type", is("CREDIT")))
.andExpect(jsonPath("$[0].transactions[0].amount", is(1.0)));
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.siriusxi.blueharvest.bank.as;

import org.junit.jupiter.api.Test;
import org.siriusxi.blueharvest.bank.as.persistence.AccountRepository;
import org.siriusxi.blueharvest.bank.as.persistence.entity.AccountEntity;
import org.siriusxi.blueharvest.bank.common.api.composite.account.AccountType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;

import java.math.BigDecimal;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

@DataJpaTest
class AccountRepositoryLayerTests {

@Autowired
private AccountRepository accountRepository;

@Test
void whenFindByCustomerId_thenReturnAccounts() {
// given
accountRepository.saveAll(List.of(
new AccountEntity(99, new BigDecimal("100.20")),
new AccountEntity(99, new BigDecimal("200.20"))));

// when
var accounts = accountRepository.findByCustomerId(99);

var account = accounts.get(0);

// then
assertThat(accounts.size()).isEqualTo(2);

assertThat(account.getId()).isEqualTo(1);
assertThat(account.getCustomerId()).isEqualTo(99);
assertThat(account.getBalance()).isEqualTo(new BigDecimal("100.20"));
assertThat(account.getType()).isEqualTo(AccountType.CURRENT);
}
}

This file was deleted.

Loading

0 comments on commit d1b2e35

Please sign in to comment.