package roomescape.payment.implement import com.ninjasquad.springmockk.MockkClear import com.ninjasquad.springmockk.clear import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import io.mockk.* import roomescape.payment.infrastructure.persistence.CanceledPaymentEntity import roomescape.payment.infrastructure.persistence.CanceledPaymentRepository import roomescape.payment.infrastructure.persistence.PaymentEntity import roomescape.payment.infrastructure.persistence.PaymentRepository import roomescape.reservation.infrastructure.persistence.ReservationEntity import roomescape.util.PaymentFixture import roomescape.util.ReservationFixture import roomescape.util.TsidFactory import java.time.OffsetDateTime class PaymentWriterTest : FunSpec({ val paymentRepository: PaymentRepository = mockk() val canceledPaymentRepository: CanceledPaymentRepository = mockk() val paymentWriter = PaymentWriter(paymentRepository, canceledPaymentRepository, TsidFactory) val paymentKey = "paymentKey" val orderId = "orderId" val totalAmount = 1000L val approvedAt = OffsetDateTime.now() context("create") { val reservation: ReservationEntity = ReservationFixture.create(id = 1L) test("결제 정보를 저장한다.") { val slot = slot() every { paymentRepository.save(capture(slot)) } returns mockk() paymentWriter.create(paymentKey, orderId, totalAmount, approvedAt, reservation) verify(exactly = 1) { paymentRepository.save(any()) } slot.captured.also { it.paymentKey shouldBe paymentKey it.orderId shouldBe orderId it.totalAmount shouldBe totalAmount it.approvedAt shouldBe approvedAt } paymentRepository.clear(MockkClear.AFTER) } } context("createCanceled") { val cancelReason = "고객 요청" val canceledAt = OffsetDateTime.now() afterTest { clearMocks(paymentRepository) clearMocks(canceledPaymentRepository) } test("PaymentEntity를 받아 저장한다.") { val payment: PaymentEntity = PaymentFixture.create(id = 1L) val slot = slot() every { canceledPaymentRepository.save(capture(slot)) } returns mockk() every { paymentRepository.deleteByPaymentKey(paymentKey) } returns Unit paymentWriter.createCanceled(payment, cancelReason, canceledAt) verify(exactly = 1) { canceledPaymentRepository.save(any()) } verify(exactly = 1) { paymentRepository.deleteByPaymentKey(any()) } slot.captured.also { it.paymentKey shouldBe payment.paymentKey it.cancelAmount shouldBe payment.totalAmount it.approvedAt shouldBe payment.approvedAt } } test("취소 정보를 받아 저장한다.") { val slot = slot() every { canceledPaymentRepository.save(capture(slot)) } returns mockk() every { paymentRepository.deleteByPaymentKey(paymentKey) } returns Unit paymentWriter.createCanceled( cancelReason = cancelReason, cancelAmount = totalAmount, canceledAt = canceledAt, approvedAt = approvedAt, paymentKey = paymentKey ) verify(exactly = 1) { canceledPaymentRepository.save(any()) } verify(exactly = 1) { paymentRepository.deleteByPaymentKey(any()) } slot.captured.also { it.paymentKey shouldBe paymentKey it.cancelAmount shouldBe totalAmount it.approvedAt shouldBe approvedAt } } } })