PaymentGatewayIntegrationTest.java
Bridget/payment_solutions/src/test/java/com/checkout/payment/gateway/integration/PaymentGatewayIntegrationTest.java
package com.checkout.payment.gateway.integration;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.core.api.Assertions.assertThat;
import com.checkout.payment.gateway.model.GetPaymentResponse;
import com.checkout.payment.gateway.model.PostPaymentRequest;
import com.checkout.payment.gateway.model.PostPaymentResponse;
import com.checkout.payment.gateway.security.ApiKeyAuthenticationFilter;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import java.util.UUID;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles({"integration"})
@Testcontainers(disabledWithoutDocker = true)
class PaymentGatewayIntegrationTest {
private static final int BANK_WIREMOCK_PORT = 19100;
private static final WireMockServer BANK_WIRE_MOCK = new WireMockServer(
WireMockConfiguration.options().port(BANK_WIREMOCK_PORT));
@Container
static final PostgreSQLContainer<?> POSTGRES = new PostgreSQLContainer<>("postgres:15-alpine")
.withDatabaseName("payment_gateway")
.withUsername("payment")
.withPassword("payment");
static {
BANK_WIRE_MOCK.start();
}
@AfterAll
static void tearDown() {
BANK_WIRE_MOCK.stop();
}
@DynamicPropertySource
static void registerProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", POSTGRES::getJdbcUrl);
registry.add("spring.datasource.username", POSTGRES::getUsername);
registry.add("spring.datasource.password", POSTGRES::getPassword);
registry.add("bank.simulator.url", () -> "http://localhost:" + BANK_WIREMOCK_PORT);
registry.add("gateway.security.enabled", () -> "true");
registry.add("gateway.security.merchant-api-keys", () -> "integration-merchant-key");
registry.add("gateway.security.admin-api-keys", () -> "integration-admin-key");
registry.add("gateway.ratelimit.enabled", () -> "false");
}
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@BeforeEach
void resetBankStub() {
BANK_WIRE_MOCK.resetAll();
BANK_WIRE_MOCK.stubFor(post(urlEqualTo("/payments"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("{\"authorized\":true,\"authorization_code\":\""
+ UUID.randomUUID() + "\"}")));
}
@Test
void postPayment_persistsAndCanBeRetrieved() {
PostPaymentRequest request = new PostPaymentRequest();
request.setCardNumber("2222405343248877");
request.setExpiryMonth(4);
request.setExpiryYear(2030);
request.setCurrency("GBP");
request.setAmount(100);
request.setCvv("123");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set(ApiKeyAuthenticationFilter.API_KEY_HEADER, "integration-merchant-key");
headers.set("Idempotency-Key", UUID.randomUUID().toString());
String base = "http://localhost:" + port + "/api/v1";
ResponseEntity<PostPaymentResponse> created = restTemplate.exchange(
base + "/payments",
HttpMethod.POST,
new HttpEntity<>(request, headers),
PostPaymentResponse.class);
assertThat(created.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(created.getBody()).isNotNull();
assertThat(created.getBody().getStatus().getName()).isEqualTo("Authorized");
UUID id = created.getBody().getId();
ResponseEntity<GetPaymentResponse> fetched = restTemplate.exchange(
base + "/payments/" + id,
HttpMethod.GET,
new HttpEntity<>(headers),
GetPaymentResponse.class);
assertThat(fetched.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(fetched.getBody()).isNotNull();
assertThat(fetched.getBody().getId()).isEqualTo(id);
assertThat(fetched.getBody().getAmount()).isEqualTo(100);
BANK_WIRE_MOCK.verify(postRequestedFor(urlEqualTo("/payments"))
.withRequestBody(matchingJsonPath("$.card_number", equalTo("2222405343248877")))
.withRequestBody(matchingJsonPath("$.expiry_date", equalTo("04/2030")))
.withRequestBody(matchingJsonPath("$.currency", equalTo("GBP")))
.withRequestBody(matchingJsonPath("$.amount", equalTo("100")))
.withRequestBody(matchingJsonPath("$.cvv", equalTo("123"))));
}
}
Artigos 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).
Ler artigo →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).
Ler artigo →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).
Ler artigo →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).
Ler artigo →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).
Ler artigo →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).
Ler artigo →