Skip to content
Snippets Groups Projects
Commit a677b73f authored by Zdeněk Sedláček's avatar Zdeněk Sedláček
Browse files

Merge branch 'processor/it-tests' into 'develop'

Processor/it tests

See merge request xpitak/PA165-Banking-System!35
parents 5e326c1b 1279d762
No related branches found
No related tags found
No related merge requests found
......@@ -12,7 +12,7 @@ import java.math.BigDecimal;
import java.util.Currency;
/**
* Handler for transaction of type ${@link cz.muni.pa165.banking.domain.transaction.TransactionType#WITHDRAWAL}.
* Handler for transaction of type ${@link cz.muni.pa165.banking.domain.transaction.TransactionType#TRANSFER}.
* Customer may send a specified amount of money to a foreign account, where the currency of both accounts does
* not have to be the same. The amount of money is calculated via ${@link cz.muni.pa165.banking.domain.money.CurrencyConverter}
* using the target account's currency.
......
......@@ -9,6 +9,8 @@ import cz.muni.pa165.banking.domain.process.Process;
import cz.muni.pa165.banking.domain.process.ProcessOperations;
import cz.muni.pa165.banking.domain.process.status.Status;
import cz.muni.pa165.banking.domain.process.status.StatusInformation;
import cz.muni.pa165.banking.transaction.processor.dto.ProcessStatusDto;
import cz.muni.pa165.banking.transaction.processor.dto.ProcessStatusListDto;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
......@@ -25,10 +27,14 @@ import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import java.time.*;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
......@@ -46,6 +52,9 @@ public class ProcessControllerIT {
@Autowired
private ObjectMapper objectMapper;
@Autowired
private ProcessRepositoryJpa repository;
@MockBean
private ExchangeRatesApi apiMock;
......@@ -55,34 +64,45 @@ public class ProcessControllerIT {
private static final Instant instant = LocalDateTime.of(2024, Month.APRIL, 24, 12, 0, 0).toInstant(ZoneOffset.UTC);
private static Set<Process> storedProcesses;
private static Process processedProcess;
@BeforeAll
public static void initDb(@Autowired ProcessRepositoryJpa repository) {
repository.save(Process.createNew());
repository.save(Process.createNew());
Process processed1 = Process.createNew();
ProcessOperations.changeState(processed1, new StatusInformation(instant, Status.PENDING, "PENDING"));
repository.save(processed1);
Process process1 = Process.createNew();
ProcessOperations.changeState(process1, new StatusInformation(instant, Status.PENDING, "PENDING"));
repository.save(process1);
Process processed2 = Process.createNew();
ProcessOperations.changeState(processed2, new StatusInformation(instant, Status.PENDING, "PENDING"));
repository.save(processed2);
Process process2 = Process.createNew();
ProcessOperations.changeState(process2, new StatusInformation(instant, Status.PENDING, "PENDING"));
repository.save(process2);
LocalDateTime currentDateTime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
LocalDateTime newDateTime = currentDateTime.minusDays(10);
Instant tenDaysAgo = newDateTime.toInstant(ZoneOffset.UTC);
Process processed4 = Process.createNew();
ProcessOperations.changeState(processed4, new StatusInformation(tenDaysAgo, Status.CREATED, "CREATED"));
repository.save(processed4);
processedProcess = Process.createNew();
ProcessOperations.changeState(processedProcess, new StatusInformation(tenDaysAgo, Status.PROCESSED, "PROCESSED"));
repository.save(processedProcess);
Process processed5 = Process.createNew();
ProcessOperations.changeState(processed5, new StatusInformation(tenDaysAgo, Status.PENDING, "PENDING"));
repository.save(processed5);
Process process4 = Process.createNew();
ProcessOperations.changeState(process4, new StatusInformation(tenDaysAgo, Status.CREATED, "CREATED"));
repository.save(process4);
Process process5 = Process.createNew();
ProcessOperations.changeState(process5, new StatusInformation(tenDaysAgo, Status.PENDING, "PENDING"));
repository.save(process5);
storedProcesses = Set.of(process1, process2, processedProcess, process4, process5);
}
@WithMockUser(authorities = "SCOPE_test_2")
@Test
@WithMockUser(authorities = "SCOPE_test_2")
public void resolveStaleProcesses() throws Exception {
LocalDateTime currentDateTime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
LocalDateTime newDateTime = currentDateTime.minusDays(1);
......@@ -91,6 +111,7 @@ public class ProcessControllerIT {
List<Process> staleProcesses = service.unresolvedProcessesToDate(yesterday);
for (Process process : staleProcesses) {
assertNotEquals(Status.FAILED, process.getStatus());
assertNotEquals(Status.PROCESSED, process.getStatus());
}
List<UUID> staleProcessIds = staleProcesses.stream()
.map(Process::getUuid)
......@@ -114,5 +135,61 @@ public class ProcessControllerIT {
}
}
@Test
@WithMockUser(authorities = "SCOPE_test_2")
public void fetchProcessedProcesses() throws Exception {
Set<UUID> expectedProcessIds = storedProcesses.stream()
.filter(p -> p.getStatus().equals(Status.PROCESSED))
.map(Process::getUuid)
.collect(Collectors.toSet());
MvcResult response = mockMvc.perform(get("/processes/v1/PROCESSED")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andReturn();
String jsonResponse = response.getResponse().getContentAsString();
List<ProcessStatusDto> foundProcesses = objectMapper.readValue(jsonResponse, ProcessStatusListDto.class).getProcesses();
assertEquals(expectedProcessIds.size(), foundProcesses.size());
for (ProcessStatusDto process : foundProcesses) {
assertEquals(process.getStatus().getStatus().getValue(), "PROCESSED");
assertTrue(expectedProcessIds.contains(process.getIdentifier()));
}
}
@Test
@WithMockUser(authorities = "SCOPE_test_2")
public void fetchValidProcessStatus() throws Exception {
MvcResult response = mockMvc.perform(get("/process/v1/{uuid}/status", processedProcess.getUuid())
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andReturn();
String jsonResponse = response.getResponse().getContentAsString();
ProcessStatusDto status = objectMapper.readValue(jsonResponse, ProcessStatusDto.class);
assertEquals(processedProcess.getUuid(), status.getIdentifier());
assertEquals(processedProcess.getStatus().name(), status.getStatus().getStatus().getValue());
}
@Test
@WithMockUser(authorities = "SCOPE_test_2")
public void fetchInvalidProcessStatus() throws Exception {
MvcResult response = mockMvc.perform(get("/process/v1/{uuid}/status", UUID.randomUUID())
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isNotFound())
.andReturn();
String jsonResponse = response.getResponse().getContentAsString();
LinkedHashMap JSON = objectMapper.readValue(jsonResponse, LinkedHashMap.class);
assertTrue(JSON.containsKey("status"));
assertEquals("NOT_FOUND", JSON.get("status"));
assertTrue(JSON.containsKey("message"));
assertEquals("Entity not present in repository", JSON.get("message"));
}
}
package cz.muni.pa165.banking.application.integration;
import com.fasterxml.jackson.databind.ObjectMapper;
import cz.muni.pa165.banking.account.management.AccountApi;
import cz.muni.pa165.banking.account.management.dto.AccountDto;
import cz.muni.pa165.banking.account.query.CustomerServiceApi;
import cz.muni.pa165.banking.account.query.SystemServiceApi;
import cz.muni.pa165.banking.account.query.dto.TransactionType;
import cz.muni.pa165.banking.application.proxy.rate.ExchangeRatesApi;
import cz.muni.pa165.banking.domain.account.Account;
import cz.muni.pa165.banking.domain.messaging.MessageProducer;
import cz.muni.pa165.banking.domain.money.Money;
import cz.muni.pa165.banking.domain.process.Process;
import cz.muni.pa165.banking.domain.process.ProcessFactory;
import cz.muni.pa165.banking.domain.process.repository.ProcessRepository;
import cz.muni.pa165.banking.domain.process.repository.ProcessTransactionRepository;
import cz.muni.pa165.banking.domain.transaction.Transaction;
import cz.muni.pa165.banking.transaction.processor.dto.*;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import java.math.BigDecimal;
import java.util.Currency;
import java.util.LinkedHashMap;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureDataJpa
@ExtendWith(MockitoExtension.class)
@AutoConfigureMockMvc
public class TransactionControllerIT {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@MockBean
private ExchangeRatesApi apiMock;
@MockBean
private SecurityFilterChain securityFilterChainMock;
@MockBean
private AccountApi accountApi;
@MockBean
private CustomerServiceApi publicBalanceApi;
@MockBean
private SystemServiceApi privateBalanceApi;
private static Process createdProcess;
@BeforeAll
static void initDb(@Autowired ProcessRepository repository, @Autowired ProcessTransactionRepository transactionRepository) {
Account a1 = new Account("acc1");
Account a2 = new Account("acc2");
Money money = new Money(BigDecimal.ONE, Currency.getInstance("CZK"));
Transaction transaction = new Transaction(a1, a2, cz.muni.pa165.banking.domain.transaction.TransactionType.TRANSFER, money, "transfer 1czk");
MessageProducer producer = mock(MessageProducer.class);
createdProcess = new ProcessFactory(transactionRepository, repository).create(transaction, producer);
}
@Test
@WithMockUser(authorities = "SCOPE_test_2")
public void processTransferBetweenAccounts() throws Exception {
Account source = new Account("acc_source");
Account target = new Account("acc_target");
when(accountApi.findByAccountNumber(source.getAccountNumber())).thenReturn(ResponseEntity.ok(new AccountDto().number("acc_source").currency("CZK")));
when(accountApi.findByAccountNumber(target.getAccountNumber())).thenReturn(ResponseEntity.ok(new AccountDto().number("acc_target").currency("CZK")));
when(publicBalanceApi.getBalance(source.getAccountNumber())).thenReturn(ResponseEntity.ok(BigDecimal.valueOf(1000)));
String requestBody = objectMapper.writeValueAsString(new TransactionDto()
.source(new cz.muni.pa165.banking.transaction.processor.dto.AccountDto().accountNumber("acc_source"))
.target(new cz.muni.pa165.banking.transaction.processor.dto.AccountDto().accountNumber("acc_target"))
.type(TransactionTypeDto.TRANSFER)
.amount(new MoneyDto().amount(BigDecimal.valueOf(100)).currency("CZK"))
.detail("TRANSFER TEST"));
MvcResult response = mockMvc.perform(
put("/transaction/v1/process")
.content(requestBody)
.contentType(MediaType.APPLICATION_JSON)
)
.andExpect(status().isOk())
.andReturn();
String jsonResponse = response.getResponse().getContentAsString();
ProcessDto process = objectMapper.readValue(jsonResponse, ProcessDto.class);
assertEquals(StatusDto.CREATED, process.getStatus());
verify(privateBalanceApi).addTransactionToBalance(source.getAccountNumber(), BigDecimal.valueOf(-100), process.getIdentifier(), TransactionType.TRANSFER);
verify(privateBalanceApi).addTransactionToBalance(target.getAccountNumber(), BigDecimal.valueOf(100), process.getIdentifier(), TransactionType.TRANSFER);
}
@Test
@WithMockUser(authorities = "SCOPE_test_2")
public void getValidProcessStatus() throws Exception {
MvcResult response = mockMvc.perform(
get("/transaction/v1/status")
.header("x-process-uuid", createdProcess.getUuid())
.contentType(MediaType.APPLICATION_JSON)
)
.andExpect(status().isOk())
.andReturn();
String jsonResponse = response.getResponse().getContentAsString();
ProcessDetailDto detail = objectMapper.readValue(jsonResponse, ProcessDetailDto.class);
assertEquals(createdProcess.getUuid(), detail.getIdentifier());
assertEquals(StatusDto.CREATED, detail.getStatus());
}
@Test
@WithMockUser(authorities = "SCOPE_test_2")
public void getNonexistentProcessStatus() throws Exception {
MvcResult response = mockMvc.perform(
get("/transaction/v1/status")
.header("x-process-uuid", UUID.randomUUID())
.contentType(MediaType.APPLICATION_JSON)
)
.andExpect(status().isNotFound())
.andReturn();
String jsonResponse = response.getResponse().getContentAsString();
LinkedHashMap JSON = objectMapper.readValue(jsonResponse, LinkedHashMap.class);
assertTrue(JSON.containsKey("status"));
assertEquals("NOT_FOUND", JSON.get("status"));
assertTrue(JSON.containsKey("message"));
assertEquals("Entity not present in repository", JSON.get("message"));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment