PaymentGatewayServiceTest.java
Bridget/payment-gateway-challenge-java/src/test/java/com/checkout/payment/gateway/service/PaymentGatewayServiceTest.java
package com.checkout.payment.gateway.service;
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.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.checkout.payment.gateway.enums.PaymentStatus;
import com.checkout.payment.gateway.exception.BankErrorException;
import com.checkout.payment.gateway.exception.EventProcessingException;
import com.checkout.payment.gateway.model.BankPaymentRequest;
import com.checkout.payment.gateway.model.BankPaymentResponse;
import com.checkout.payment.gateway.model.PaymentMapper;
import com.checkout.payment.gateway.model.PostPaymentRequest;
import com.checkout.payment.gateway.model.PostPaymentResponse;
import com.checkout.payment.gateway.repository.PaymentsRepository;
import java.util.Optional;
import java.util.UUID;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.HttpStatus;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;
@ExtendWith(MockitoExtension.class)
class PaymentGatewayServiceTest {
private static final String BANK_URL = "http://localhost:8080/payments";
@Mock
private PaymentsRepository paymentsRepository;
@Mock
private RestTemplate restTemplate;
private PaymentGatewayService paymentGatewayService;
@BeforeEach
void setUp() {
paymentGatewayService = new PaymentGatewayService(paymentsRepository, restTemplate, BANK_URL);
}
@Test
void shouldReturnPaymentWhenIdExists() {
PostPaymentResponse payment =
PostPaymentResponse.builder()
.cardNumberLastFour("4321")
.id(UUID.randomUUID())
.amount(10)
.currency("USD")
.status(PaymentStatus.AUTHORIZED)
.expiryYear(2024)
.expiryMonth(12)
.build();
when(paymentsRepository.get(payment.getId())).thenReturn(Optional.of(payment));
assertEquals(
PaymentMapper.toGetResponse(payment), paymentGatewayService.getPaymentById(payment.getId()));
}
@Test
void shouldThrowExceptionWhenIdNotExists() {
UUID id = UUID.randomUUID();
when(paymentsRepository.get(id)).thenReturn(Optional.empty());
assertThrows(EventProcessingException.class, () -> paymentGatewayService.getPaymentById(id));
}
@Test
void shouldReturnAuthorizedWhenBankAuthorized() {
BankPaymentRequest request =
BankPaymentRequest.builder()
.cardNumber("2222405343248877")
.expiryDate("04/2025")
.currency("GBP")
.amount(100)
.cvv("123")
.build();
when(restTemplate.postForObject(eq(BANK_URL), eq(request), eq(BankPaymentResponse.class)))
.thenReturn(
BankPaymentResponse.builder()
.authorized(true)
.authorizationCode("123456")
.build());
BankPaymentResponse response = paymentGatewayService.sendPaymentRequestToBank(request);
assertTrue(response.isAuthorized());
verify(restTemplate).postForObject(eq(BANK_URL), eq(request), eq(BankPaymentResponse.class));
}
@Test
void shouldThrowExceptionWhenBankServiceUnavailable() {
BankPaymentRequest request =
BankPaymentRequest.builder()
.cardNumber("2222405343248870")
.expiryDate("04/2025")
.currency("GBP")
.amount(100)
.cvv("123")
.build();
when(restTemplate.postForObject(eq(BANK_URL), eq(request), eq(BankPaymentResponse.class)))
.thenThrow(new HttpServerErrorException(HttpStatus.SERVICE_UNAVAILABLE));
assertThrows(BankErrorException.class, () -> paymentGatewayService.sendPaymentRequestToBank(request));
}
@Test
void shouldThrowBankErrorExceptionWhenBankReturnsBadRequest() {
BankPaymentRequest request =
BankPaymentRequest.builder()
.cardNumber("2222405343248870")
.expiryDate("04/2025")
.currency("GBP")
.amount(100)
.cvv("123")
.build();
when(restTemplate.postForObject(eq(BANK_URL), eq(request), eq(BankPaymentResponse.class)))
.thenThrow(new HttpClientErrorException(HttpStatus.BAD_REQUEST));
BankErrorException ex =
assertThrows(
BankErrorException.class, () -> paymentGatewayService.sendPaymentRequestToBank(request));
assertEquals(400, ex.getStatusCode().value());
}
@Test
void shouldMaskCardNumberWhenGeneratingResponse() {
PostPaymentRequest request =
PostPaymentRequest.builder()
.cardNumber("2222405343248878")
.amount(10)
.currency("USD")
.expiryYear(2024)
.expiryMonth(12)
.cvv("123")
.build();
ArgumentCaptor<BankPaymentRequest> bankReq = ArgumentCaptor.forClass(BankPaymentRequest.class);
when(restTemplate.postForObject(eq(BANK_URL), bankReq.capture(), eq(BankPaymentResponse.class)))
.thenReturn(
BankPaymentResponse.builder()
.authorized(true)
.authorizationCode("123456")
.build());
assertEquals("8878", paymentGatewayService.createPayment(request).getCardNumberLastFour());
verify(paymentsRepository).add(any(PostPaymentResponse.class));
}
@Test
void shouldReturnAuthorizedStatusWhenBankAuthorized() {
PostPaymentRequest request =
PostPaymentRequest.builder()
.cardNumber("2222405343248878")
.amount(10)
.currency("USD")
.expiryYear(2024)
.expiryMonth(12)
.cvv("123")
.build();
when(restTemplate.postForObject(eq(BANK_URL), any(BankPaymentRequest.class), eq(BankPaymentResponse.class)))
.thenReturn(
BankPaymentResponse.builder()
.authorized(true)
.authorizationCode("123456")
.build());
PostPaymentResponse result = paymentGatewayService.processPayment(request);
assertEquals(PaymentStatus.AUTHORIZED, result.getStatus());
}
@Test
void shouldReturnDeclinedStatusWhenBankNotAuthorized() {
PostPaymentRequest request =
PostPaymentRequest.builder()
.cardNumber("2222405343248878")
.amount(10)
.currency("USD")
.expiryYear(2024)
.expiryMonth(12)
.cvv("123")
.build();
when(restTemplate.postForObject(eq(BANK_URL), any(BankPaymentRequest.class), eq(BankPaymentResponse.class)))
.thenReturn(
BankPaymentResponse.builder()
.authorized(false)
.authorizationCode("")
.build());
PostPaymentResponse result = paymentGatewayService.processPayment(request);
assertEquals(PaymentStatus.DECLINED, result.getStatus());
}
}
Artículos relacionados
PaymentGatewayApplication.java
PaymentGatewayApplication.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/PaymentGatewayApplication.java).
Leer artículo →ApplicationConfiguration.java
ApplicationConfiguration.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/configuration/ApplicationConfiguration.java).
Leer artículo →RequestResponseLogger.java
RequestResponseLogger.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/configuration/RequestResponseLogger.java).
Leer artículo →PaymentGatewayController.java
PaymentGatewayController.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/controller/PaymentGatewayController.java).
Leer artículo →PaymentStatus.java
PaymentStatus.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/enums/PaymentStatus.java).
Leer artículo →BankErrorException.java
BankErrorException.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/exception/BankErrorException.java).
Leer artículo →