151 lines
6.6 KiB
Java

package roomescape.payment.business;
import static org.assertj.core.api.Assertions.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.Sql.ExecutionPhase;
import roomescape.common.exception.RoomescapeException;
import roomescape.member.infrastructure.persistence.MemberEntity;
import roomescape.member.infrastructure.persistence.MemberRepository;
import roomescape.member.infrastructure.persistence.Role;
import roomescape.payment.infrastructure.persistence.CanceledPaymentEntity;
import roomescape.payment.infrastructure.persistence.CanceledPaymentRepository;
import roomescape.payment.web.PaymentApprove;
import roomescape.payment.web.PaymentCancel;
import roomescape.payment.web.ReservationPaymentResponse;
import roomescape.reservation.infrastructure.persistence.Reservation;
import roomescape.reservation.infrastructure.persistence.ReservationRepository;
import roomescape.reservation.infrastructure.persistence.ReservationStatus;
import roomescape.reservation.infrastructure.persistence.ReservationTimeEntity;
import roomescape.reservation.infrastructure.persistence.ReservationTimeRepository;
import roomescape.theme.infrastructure.persistence.ThemeEntity;
import roomescape.theme.infrastructure.persistence.ThemeRepository;
@SpringBootTest
@Sql(scripts = "/truncate.sql", executionPhase = ExecutionPhase.BEFORE_TEST_METHOD)
class PaymentServiceTest {
@Autowired
private PaymentService paymentService;
@Autowired
private ReservationRepository reservationRepository;
@Autowired
private MemberRepository memberRepository;
@Autowired
private ReservationTimeRepository reservationTimeRepository;
@Autowired
private ThemeRepository themeRepository;
@Autowired
private CanceledPaymentRepository canceledPaymentRepository;
@Test
@DisplayName("결제 정보를 저장한다.")
void savePayment() {
// given
PaymentApprove.Response paymentInfo = new PaymentApprove.Response("payment-key", "order-id",
OffsetDateTime.now(), 10000L);
LocalDateTime localDateTime = LocalDateTime.now().plusHours(1L);
LocalDate date = localDateTime.toLocalDate();
ReservationTimeEntity time = reservationTimeRepository.save(new ReservationTimeEntity(null, localDateTime.toLocalTime()));
MemberEntity member = memberRepository.save(
new MemberEntity(null, "member", "email@email.com", "password", Role.MEMBER));
ThemeEntity theme = themeRepository.save(new ThemeEntity(null, "name", "desc", "thumbnail"));
Reservation reservation = reservationRepository.save(new Reservation(date, time, theme, member,
ReservationStatus.CONFIRMED));
// when
ReservationPaymentResponse reservationPaymentResponse = paymentService.savePayment(paymentInfo, reservation);
// then
assertThat(reservationPaymentResponse.reservation().id).isEqualTo(reservation.getId());
assertThat(reservationPaymentResponse.paymentKey()).isEqualTo(paymentInfo.paymentKey);
}
@Test
@DisplayName("예약 ID로 결제 정보를 제거하고, 결제 취소 테이블에 취소 정보를 저장한다.")
void cancelPaymentByAdmin() {
// given
PaymentApprove.Response paymentInfo = new PaymentApprove.Response("payment-key", "order-id",
OffsetDateTime.now(), 10000L);
LocalDateTime localDateTime = LocalDateTime.now().plusHours(1L);
LocalDate date = localDateTime.toLocalDate();
ReservationTimeEntity time = reservationTimeRepository.save(new ReservationTimeEntity(null, localDateTime.toLocalTime()));
MemberEntity member = memberRepository.save(
new MemberEntity(null, "member", "email@email.com", "password", Role.MEMBER));
ThemeEntity theme = themeRepository.save(new ThemeEntity(null, "name", "desc", "thumbnail"));
Reservation reservation = reservationRepository.save(new Reservation(date, time, theme, member,
ReservationStatus.CONFIRMED));
paymentService.savePayment(paymentInfo, reservation);
// when
PaymentCancel.Request paymentCancelRequest = paymentService.cancelPaymentByAdmin(reservation.getId());
// then
assertThat(canceledPaymentRepository.findByPaymentKey("payment-key")).isNotNull();
assertThat(paymentCancelRequest.paymentKey).isEqualTo(paymentInfo.paymentKey);
assertThat(paymentCancelRequest.cancelReason).isEqualTo("고객 요청");
assertThat(paymentCancelRequest.amount).isEqualTo(10000L);
}
@Test
@DisplayName("입력된 예약 ID에 대한 결제 정보가 없으면 예외가 발생한다.")
void cancelPaymentByAdminWithNonExistentReservationId() {
// given
Long nonExistentReservationId = 1L;
// when
assertThatThrownBy(() -> paymentService.cancelPaymentByAdmin(nonExistentReservationId))
.isInstanceOf(RoomescapeException.class);
}
@Test
@DisplayName("결제 취소 정보에 있는 취소 시간을 업데이트한다.")
void updateCanceledTime() {
// given
PaymentApprove.Response paymentInfo = new PaymentApprove.Response("payment-key", "order-id",
OffsetDateTime.now(), 10000L);
LocalDateTime localDateTime = LocalDateTime.now().plusHours(1L);
LocalDate date = localDateTime.toLocalDate();
ReservationTimeEntity time = reservationTimeRepository.save(new ReservationTimeEntity(null, localDateTime.toLocalTime()));
MemberEntity member = memberRepository.save(
new MemberEntity(null, "member", "email@email.com", "password", Role.MEMBER));
ThemeEntity theme = themeRepository.save(new ThemeEntity(null, "name", "desc", "thumbnail"));
Reservation reservation = reservationRepository.save(new Reservation(date, time, theme, member,
ReservationStatus.CONFIRMED));
paymentService.savePayment(paymentInfo, reservation);
paymentService.cancelPaymentByAdmin(reservation.getId());
// when
OffsetDateTime canceledAt = OffsetDateTime.now().plusHours(2L);
paymentService.updateCanceledTime(paymentInfo.paymentKey, canceledAt);
// then
CanceledPaymentEntity canceledPayment = canceledPaymentRepository.findByPaymentKey(paymentInfo.paymentKey);
assertThat(canceledPayment).isNotNull();
assertThat(canceledPayment.getCanceledAt()).isEqualTo(canceledAt);
}
@Test
@DisplayName("결제 취소 시간을 업데이트 할 때, 입력한 paymentKey가 존재하지 않으면 예외가 발생한다.")
void updateCanceledTimeWithNonExistentPaymentKey() {
// given
OffsetDateTime canceledAt = OffsetDateTime.now().plusHours(2L);
// when
assertThatThrownBy(() -> paymentService.updateCanceledTime("non-existent-payment-key", canceledAt))
.isInstanceOf(RoomescapeException.class);
}
}