118 lines
4.8 KiB
Java

package roomescape.payment.infrastructure.client;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.*;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.*;
import static org.springframework.test.web.client.response.MockRestResponseCreators.*;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.web.client.MockRestServiceServer;
import roomescape.common.exception.ErrorType;
import roomescape.common.exception.RoomescapeException;
import roomescape.payment.SampleTossPaymentConst;
import roomescape.payment.web.PaymentApprove;
import roomescape.payment.web.PaymentCancel;
@RestClientTest(TossPaymentClient.class)
class TossPaymentClientTest {
@Autowired
private TossPaymentClient tossPaymentClient;
@Autowired
private MockRestServiceServer mockServer;
@Test
@DisplayName("결제를 승인한다.")
void confirmPayment() {
// given
mockServer.expect(requestTo("/v1/payments/confirm"))
.andExpect(method(HttpMethod.POST))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(content().json(SampleTossPaymentConst.paymentRequestJson))
.andRespond(withStatus(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(SampleTossPaymentConst.confirmJson));
// when
PaymentApprove.Request paymentRequest = SampleTossPaymentConst.paymentRequest;
PaymentApprove.Response paymentResponse = tossPaymentClient.confirmPayment(paymentRequest);
// then
assertThat(paymentResponse.paymentKey).isEqualTo(paymentRequest.paymentKey);
assertThat(paymentResponse.orderId).isEqualTo(paymentRequest.orderId);
}
@Test
@DisplayName("결제를 취소한다.")
void cancelPayment() {
// given
mockServer.expect(requestTo("/v1/payments/5EnNZRJGvaBX7zk2yd8ydw26XvwXkLrx9POLqKQjmAw4b0e1/cancel"))
.andExpect(method(HttpMethod.POST))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(content().json(SampleTossPaymentConst.cancelRequestJson))
.andRespond(withStatus(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(SampleTossPaymentConst.cancelJson));
// when
PaymentCancel.Request cancelRequest = SampleTossPaymentConst.cancelRequest;
PaymentCancel.Response paymentCancelResponse = tossPaymentClient.cancelPayment(cancelRequest);
// then
assertThat(paymentCancelResponse.cancelStatus).isEqualTo("DONE");
assertThat(paymentCancelResponse.cancelReason).isEqualTo(cancelRequest.cancelReason);
}
@Test
@DisplayName("결제 승인 중 400 에러가 발생한다.")
void confirmPaymentWithError() {
// given
mockServer.expect(requestTo("/v1/payments/confirm"))
.andExpect(method(HttpMethod.POST))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(content().json(SampleTossPaymentConst.paymentRequestJson))
.andRespond(withStatus(HttpStatus.BAD_REQUEST)
.contentType(MediaType.APPLICATION_JSON)
.body(SampleTossPaymentConst.tossPaymentErrorJson));
// when & then
assertThatThrownBy(() -> tossPaymentClient.confirmPayment(SampleTossPaymentConst.paymentRequest))
.isInstanceOf(RoomescapeException.class)
.hasFieldOrPropertyWithValue("errorType", ErrorType.PAYMENT_ERROR)
.hasFieldOrPropertyWithValue("invalidValue",
"[ErrorCode = ERROR_CODE, ErrorMessage = Error message]")
.hasFieldOrPropertyWithValue("httpStatus", HttpStatus.BAD_REQUEST);
}
@Test
@DisplayName("결제 취소 중 500 에러가 발생한다.")
void cancelPaymentWithError() {
// given
mockServer.expect(requestTo("/v1/payments/5EnNZRJGvaBX7zk2yd8ydw26XvwXkLrx9POLqKQjmAw4b0e1/cancel"))
.andExpect(method(HttpMethod.POST))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(content().json(SampleTossPaymentConst.cancelRequestJson))
.andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR)
.contentType(MediaType.APPLICATION_JSON)
.body(SampleTossPaymentConst.tossPaymentErrorJson));
// when & then
assertThatThrownBy(() -> tossPaymentClient.cancelPayment(SampleTossPaymentConst.cancelRequest))
.isInstanceOf(RoomescapeException.class)
.hasFieldOrPropertyWithValue("errorType", ErrorType.PAYMENT_SERVER_ERROR)
.hasFieldOrPropertyWithValue("invalidValue",
"[ErrorCode = ERROR_CODE, ErrorMessage = Error message]")
.hasFieldOrPropertyWithValue("httpStatus", HttpStatus.INTERNAL_SERVER_ERROR);
}
}