Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.javafaker</groupId>
<artifactId>javafaker</artifactId>
<version>0.15</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@
@SpringBootTest
class SimpleBankingApplicationTests {

@Test
void contextLoads() {
}

}
81 changes: 81 additions & 0 deletions src/test/java/com/skypro/simplebanking/TestData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.skypro.simplebanking;

import com.github.javafaker.Faker;
import com.skypro.simplebanking.dto.BankingUserDetails;
import com.skypro.simplebanking.dto.TransferRequest;
import com.skypro.simplebanking.entity.Account;
import com.skypro.simplebanking.entity.AccountCurrency;
import com.skypro.simplebanking.entity.User;

import java.util.ArrayList;
import java.util.Random;

public class TestData {


public static final Faker faker = new Faker();

public static Long getTestRandomLong() {
return new Random().nextLong(1000);
}
public static String getTestPassword() {
return faker.number().digits(10);
}
public static String getTestUserName() {
return faker.name().name();
}

public static User getTestUser() {
User user = new User();
user.setId(getTestRandomLong());
user.setUsername(getTestUserName());
user.setPassword(getTestPassword());
user.setAccounts(new ArrayList<>());

for (AccountCurrency currency : AccountCurrency.values()) {
Account account = new Account();
account.setId(getTestRandomLong());
account.setUser(user);
account.setAccountCurrency(currency);
account.setAmount(getTestRandomLong());
user.getAccounts().add(account);
}
return user;
}

public static BankingUserDetails getAdminBankingUserDetails(User user) {
return new BankingUserDetails(getTestRandomLong(), user.getUsername(), user.getPassword(), true);
}
public static long getUserAmount(User user, AccountCurrency accountCurrency) {
return user.getAccounts()
.stream()
.filter(x -> x.getAccountCurrency().equals(accountCurrency))
.mapToLong(Account::getAmount)
.findAny()
.orElseThrow();
}
public static TransferRequest getTestTransferRequest(User fromUser, AccountCurrency fromAccountCurrency, User toUser, AccountCurrency toAccountCurrency, long amount) {
TransferRequest transferRequest = new TransferRequest();
transferRequest.setFromAccountId(fromUser.getAccounts()
.stream()
.filter(x -> x.getAccountCurrency().equals(fromAccountCurrency))
.findFirst()
.orElseThrow()
.getId());
transferRequest.setToUserId(toUser.getId());
transferRequest.setToAccountId(toUser.getAccounts()
.stream()
.filter(x -> x.getAccountCurrency().equals(toAccountCurrency))
.findFirst()
.orElseThrow()
.getId());
transferRequest.setAmount(fromUser.getAccounts()
.stream()
.filter(x -> x.getAccountCurrency().equals(AccountCurrency.RUB))
.findFirst()
.map(x -> x.getAmount() - 1)
.orElseThrow());
transferRequest.setAmount(amount);
return transferRequest;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
package com.skypro.simplebanking.controller;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.skypro.simplebanking.SimpleBankingApplication;
import com.skypro.simplebanking.dto.BalanceChangeRequest;
import com.skypro.simplebanking.dto.BankingUserDetails;
import com.skypro.simplebanking.entity.Account;
import com.skypro.simplebanking.entity.User;
import com.skypro.simplebanking.repository.UserRepository;
import com.skypro.simplebanking.repository.AccountRepository;
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.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;

import static com.skypro.simplebanking.TestData.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;

@SpringBootTest(classes = SimpleBankingApplication.class)
@AutoConfigureMockMvc
@Transactional
public class AccountControllerTests {

@Autowired
private MockMvc mockMvc;
@Autowired
private UserRepository userRepository;
@Autowired
private AccountRepository accountRepository;

private final ObjectMapper objectMapper = new ObjectMapper();
private final BalanceChangeRequest balanceChangeRequest = new BalanceChangeRequest();


@BeforeEach
void createBalanceChangeRequest(){
balanceChangeRequest.setAmount(getTestRandomLong());
}

@AfterEach
void clearTestRepository() {
userRepository.deleteAll();
accountRepository.deleteAll();
}

@Test
void getUserAccount_allDataCorrect_expectedCorrectAccount() throws Exception {
User user = userRepository.save(getTestUser());
BankingUserDetails userDetails = BankingUserDetails.from(user);

for (long id : user.getAccounts().stream().map(Account::getId).toList()) {
mockMvc.perform(get("/account/{id}", id)
.with(user(userDetails)))
.andExpect(status().isOk())
.andExpect(jsonPath("$").exists())
.andExpect(jsonPath("$.id").value(id));
}
}
@Test
void getUserAccount_notCorrectRole_expected_exception() throws Exception {
User user = userRepository.save(getTestUser());
BankingUserDetails userDetails = getAdminBankingUserDetails(user);

for (long id : user.getAccounts().stream().map(Account::getId).toList()) {
mockMvc.perform(get("/account/{id}", id)
.with(user(userDetails)))
.andExpect(status().is4xxClientError());
}
}
@Test
void getUserAccount_userDoesntExist_expected_exception() throws Exception {
User user = getTestUser();
BankingUserDetails userDetails = BankingUserDetails.from(user);

for (long id : user.getAccounts().stream().map(Account::getId).toList()) {
mockMvc.perform(get("/account/{id}", id)
.with(user(userDetails)))
.andExpect(status().is4xxClientError());
}
}

@Test
void depositToAccount_allDataCorrect_expected_ok() throws Exception {

User user = userRepository.save(getTestUser());
BankingUserDetails userDetails = BankingUserDetails.from(user);

for (Account account : user.getAccounts()) {
mockMvc.perform(post("/account/deposit/{id}", account.getId())
.with(user(userDetails))
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(balanceChangeRequest)))
.andExpect(status().isOk())
.andExpect(jsonPath("$").exists())
.andExpect(jsonPath("$.id").value(account.getId()))
.andExpect(jsonPath("$.currency").value(account.getAccountCurrency().name()))
.andExpect(jsonPath("$.amount").value(user.getAccounts()
.stream()
.filter(x -> x.getId().equals(account.getId()))
.findFirst()
.orElseThrow()
.getAmount()));
}
}
@Test
void depositToAccount_notCorrectRole_expected_exception() throws Exception {

User user = userRepository.save(getTestUser());
BankingUserDetails userDetails = getAdminBankingUserDetails(user);

for (Account account : user.getAccounts()) {
mockMvc.perform(post("/account/deposit/{id}", account.getId())
.with(user(userDetails))
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(balanceChangeRequest)))
.andExpect(status().is4xxClientError());
}
}
@Test
void depositToAccount_userDoesntExist_expected_exception() throws Exception {

User user = getTestUser();
BankingUserDetails userDetails = BankingUserDetails.from(user);

for (Account account : user.getAccounts()) {
mockMvc.perform(post("/account/deposit/{id}", account.getId())
.with(user(userDetails))
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(balanceChangeRequest)))
.andExpect(status().is4xxClientError());
}
}
@Test
void depositToAccount_notCorrectAmount_expected_exception() throws Exception {

balanceChangeRequest.setAmount(-100L);

User user = userRepository.save(getTestUser());
BankingUserDetails userDetails = BankingUserDetails.from(user);

for (Account account : user.getAccounts()) {
mockMvc.perform(post("/account/deposit/{id}", account.getId())
.with(user(userDetails))
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(balanceChangeRequest)))
.andExpect(status().is4xxClientError());
}
}
@Test
void withdrawFromAccount_allDataCorrect_expected_ok() throws Exception {
User user = userRepository.save(getTestUser());
BankingUserDetails userDetails = BankingUserDetails.from(user);
balanceChangeRequest.setAmount(1);

for (Account account : user.getAccounts()) {
mockMvc.perform(post("/account/withdraw/{id}", account.getId())
.with(user(userDetails))
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(balanceChangeRequest)))
.andExpect(status().isOk())
.andExpect(jsonPath("$").exists())
.andExpect(jsonPath("$.id").value(account.getId()))
.andExpect(jsonPath("$.currency").value(account.getAccountCurrency().name()))
.andExpect(jsonPath("$.amount").value(user.getAccounts()
.stream()
.filter(x -> x.getId().equals(account.getId()))
.findFirst()
.orElseThrow()
.getAmount()));
}
}
@Test
void withdrawFromAccount_notCorrectRole_expected_exception() throws Exception {
User user = userRepository.save(getTestUser());
BankingUserDetails userDetails = getAdminBankingUserDetails(user);
balanceChangeRequest.setAmount(1);

for (Account account : user.getAccounts()) {
mockMvc.perform(post("/account/withdraw/{id}", account.getId())
.with(user(userDetails))
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(balanceChangeRequest)))
.andExpect(status().is4xxClientError());
}
}
@Test
void withdrawFromAccount_userDoesntExist_expected_exception() throws Exception {
User user = getTestUser();
BankingUserDetails userDetails = BankingUserDetails.from(user);
balanceChangeRequest.setAmount(1);

for (Account account : user.getAccounts()) {
mockMvc.perform(post("/account/withdraw/{id}", account.getId())
.with(user(userDetails))
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(balanceChangeRequest)))
.andExpect(status().is4xxClientError());
}
}
@Test
void withdrawFromAccount_notCorrectAmount_expected_exception() throws Exception {
User user = userRepository.save(getTestUser());
BankingUserDetails userDetails = BankingUserDetails.from(user);
balanceChangeRequest.setAmount(-100L);

for (Account account : user.getAccounts()) {
mockMvc.perform(post("/account/withdraw/{id}", account.getId())
.with(user(userDetails))
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(balanceChangeRequest)))
.andExpect(status().is4xxClientError());
}
}
}
Loading