Skip to content

Commit

Permalink
CCMSPUI-381 Added check for error transactions before attempting to f…
Browse files Browse the repository at this point in the history
…ind actual client transactions. Updated tests to correlate with this.

Signed-off-by: Jamie Briggs <jamie.briggs@digital.justice.gov.uk>
  • Loading branch information
JamieBriggs-MoJ committed Jan 21, 2025
1 parent 978a965 commit b3af35d
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ void shouldGetMultipleUserFunctionTransactions() {
String requestId = "1";
// When
List<TransactionStatus> result =
transactionStatusRepository.findUserFunctionTransactionsByTransactionId(
transactionStatusRepository.findAllUserFunctionTransactionsByTransactionId(
requestId);
// Then
assertEquals(2, result.size());
Expand All @@ -165,7 +165,7 @@ void shouldGetErrorUserFunctionTransactions() {
String requestId = "500";
// When
List<TransactionStatus> result =
transactionStatusRepository.findUserFunctionTransactionsByTransactionId(
transactionStatusRepository.findAllUserFunctionTransactionsByTransactionId(
requestId);
// Then
assertEquals(1, result.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import uk.gov.laa.ccms.data.api.ClientsApi;
import uk.gov.laa.ccms.data.model.TransactionStatus;
import uk.gov.laa.ccms.data.service.ClientService;
import uk.gov.laa.ccms.data.service.ClientServiceException;

/**
* Controller class responsible for handling client-related requests.
Expand Down Expand Up @@ -36,7 +37,11 @@ public ClientsController(ClientService transactionService) {
*/
@Override
public ResponseEntity<TransactionStatus> getClientTransactionStatus(String transactionRequestId) {
return transactionService.getTransactionStatus(transactionRequestId).map(ResponseEntity::ok)
try {
return transactionService.getTransactionStatus(transactionRequestId).map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
} catch (ClientServiceException e) {
return ResponseEntity.internalServerError().build();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ public class TransactionStatus {
@Column(name = "ERROR_DESCRIPTION", length = 2000)
private String errorDescription;

/**
* This class represents the composite primary key for the TransactionStatus entity.
*
* @author Jamie Briggs
* @see TransactionStatus
*/
@Getter
@Setter
@EqualsAndHashCode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public interface TransactionStatusRepository extends ReadOnlyRepository<Transact
WHERE ts.requestId = ?1
AND ts.processName like '%USER_FUNC_AUTH%'
""")
List<TransactionStatus> findUserFunctionTransactionsByTransactionId(String transactionId);
List<TransactionStatus> findAllUserFunctionTransactionsByTransactionId(String transactionId);

/**
* Finds a client transaction with a specific transaction ID.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package uk.gov.laa.ccms.data.service;

import java.util.List;
import java.util.Optional;
import org.springframework.stereotype.Service;
import uk.gov.laa.ccms.data.mapper.TransactionStatusMapper;
Expand Down Expand Up @@ -37,9 +38,20 @@ public ClientService(TransactionStatusMapper transactionStatusMapper,
* is to be retrieved
* @return an {@code Optional} containing the {@link TransactionStatus} if found,
* or an empty {@code Optional} if not found
* @throws ClientServiceException throws exception when there was an error found
* with the associated transaction ID
*/
public Optional<TransactionStatus> getTransactionStatus(String transactionId) {
return transactionStatusRepository.findClientTransactionByTransactionId(transactionId).map(
transactionStatusMapper::toTransactionStatus);
public Optional<TransactionStatus> getTransactionStatus(String transactionId)
throws ClientServiceException {
List<uk.gov.laa.ccms.data.entity.TransactionStatus> userFuncStatus =
transactionStatusRepository.findAllUserFunctionTransactionsByTransactionId(transactionId);
if (userFuncStatus.stream().anyMatch(x -> x.getStatus()
.equalsIgnoreCase("ERROR"))) {
throw new ClientServiceException("Error found in user function");
}
return transactionStatusRepository.findClientTransactionByTransactionId(transactionId)
.map(transactionStatusMapper::toTransactionStatus);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package uk.gov.laa.ccms.data.service;

/**
* Custom exception class used to handle errors specific to the ClientService.
*
* <p>This exception is thrown when a client-related operation encounters an error
* such as a user function transaction error.</p>
*
* @author Jamie Briggs
*/
public class ClientServiceException extends RuntimeException {
public ClientServiceException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper;
import uk.gov.laa.ccms.data.model.TransactionStatus;
import uk.gov.laa.ccms.data.service.ClientService;
import uk.gov.laa.ccms.data.service.ClientServiceException;

@ExtendWith(MockitoExtension.class)
@ContextConfiguration
Expand Down Expand Up @@ -69,4 +70,15 @@ void getClientTransactionStatus_returnsNotFound() throws Exception {
.andDo(print())
.andExpect(status().isNotFound());
}

@Test
@DisplayName("getClientTransactionStatus() - Returns 500 error")
void getClientTransactionStatus_returns500Error() throws Exception {
// When
when(clientService.getTransactionStatus("ABCDEF")).thenThrow(new ClientServiceException("error"));
// Then
this.mockMvc.perform(get("/clients/status/ABCDEF"))
.andDo(print())
.andExpect(status().is5xxServerError());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package uk.gov.laa.ccms.data.service;

import static java.util.Collections.singletonList;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.Optional;
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.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import uk.gov.laa.ccms.data.mapper.TransactionStatusMapper;
import uk.gov.laa.ccms.data.model.TransactionStatus;
import uk.gov.laa.ccms.data.repository.TransactionStatusRepository;

@ExtendWith(MockitoExtension.class)
@DisplayName("ClientServiceTest")
class ClientServiceTest {

@Mock
TransactionStatusMapper transactionStatusMapper;
@Mock
TransactionStatusRepository transactionStatusRepository;

ClientService clientService;

@BeforeEach
void beforeEach() {
clientService =
new ClientService(transactionStatusMapper, transactionStatusRepository);
}

@Test
@DisplayName("Should return empty client transaction status")
void shouldReturnEmptyClientTransactionStatus() {
// Given
String transactionId = "123";
// When
Optional<TransactionStatus> transactionStatus = clientService.getTransactionStatus(
transactionId);
// Then
assertTrue(transactionStatus.isEmpty());
}

@Test
@DisplayName("Should return client transaction status")
void shouldReturnClientTransactionStatus() {
// Given
String transactionId = "123";
uk.gov.laa.ccms.data.entity.TransactionStatus entity =
uk.gov.laa.ccms.data.entity.TransactionStatus.builder()
.requestId(transactionId)
.processName("CreateClient").status("Success").build();
when(transactionStatusRepository.findClientTransactionByTransactionId(transactionId))
.thenReturn(Optional.of(entity));
TransactionStatus result = new TransactionStatus().submissionStatus("Success")
.referenceNumber("123");
when(transactionStatusMapper.toTransactionStatus(entity)).thenReturn(
result);
// When
Optional<TransactionStatus> transactionStatus = clientService.getTransactionStatus(
transactionId);
// Then
verify(transactionStatusRepository, times(1)).findAllUserFunctionTransactionsByTransactionId(
transactionId);
verify(transactionStatusRepository, times(1)).findClientTransactionByTransactionId(
transactionId);
assertTrue(transactionStatus.isPresent());
assertEquals(result, transactionStatus.get());
}

@Test
@DisplayName("Should return client transaction status even with success transaction")
void shouldReturnClientTransactionStatusEvenWithSuccessTransactions() {
// Given
String transactionId = "123";
uk.gov.laa.ccms.data.entity.TransactionStatus successTransaction =
uk.gov.laa.ccms.data.entity.TransactionStatus.builder()
.requestId(transactionId)
.processName("XXCCMS_COMMON_UTIL.USER_FUNC_AUTH").status("Success").build();
when(transactionStatusRepository.findAllUserFunctionTransactionsByTransactionId(transactionId))
.thenReturn(singletonList(successTransaction));
uk.gov.laa.ccms.data.entity.TransactionStatus entity =
uk.gov.laa.ccms.data.entity.TransactionStatus.builder()
.requestId(transactionId)
.processName("CreateClient").status("Success").build();
when(transactionStatusRepository.findClientTransactionByTransactionId(transactionId))
.thenReturn(Optional.of(entity));
TransactionStatus result = new TransactionStatus().submissionStatus("Success")
.referenceNumber("123");
when(transactionStatusMapper.toTransactionStatus(entity)).thenReturn(
result);

// When
Optional<TransactionStatus> transactionStatus = clientService.getTransactionStatus(
transactionId);

// Then
verify(transactionStatusRepository, times(1)).findAllUserFunctionTransactionsByTransactionId(
transactionId);
verify(transactionStatusRepository, times(1)).findClientTransactionByTransactionId(
transactionId);
assertTrue(transactionStatus.isPresent());
assertEquals(result, transactionStatus.get());
}

@Test
@DisplayName("Should throw exception when user function transaction is error")
void shouldThrowExceptionWhenUserFunctionTransactionIsError() {
// Given
String transactionId = "123";
uk.gov.laa.ccms.data.entity.TransactionStatus successTransaction =
uk.gov.laa.ccms.data.entity.TransactionStatus.builder()
.requestId(transactionId)
.processName("XXCCMS_COMMON_UTIL.USER_FUNC_AUTH").status("Error").build();
when(transactionStatusRepository.findAllUserFunctionTransactionsByTransactionId(transactionId))
.thenReturn(singletonList(successTransaction));

// When & Then
assertThrows(ClientServiceException.class, () -> clientService.getTransactionStatus(transactionId));
verify(transactionStatusRepository, times(1)).findAllUserFunctionTransactionsByTransactionId(
transactionId);
verify(transactionStatusRepository, times(0)).findClientTransactionByTransactionId(
transactionId);
}

}

0 comments on commit b3af35d

Please sign in to comment.