package roomescape.time.implement import io.kotest.assertions.throwables.shouldNotThrow import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import io.mockk.every import io.mockk.mockk import roomescape.reservation.implement.ReservationFinder import roomescape.time.exception.TimeErrorCode import roomescape.time.exception.TimeException import roomescape.time.infrastructure.persistence.TimeEntity import roomescape.time.infrastructure.persistence.TimeRepository import roomescape.util.TimeFixture import java.time.LocalTime class TimeValidatorTest : FunSpec({ val timeRepository: TimeRepository = mockk() val reservationFinder: ReservationFinder = mockk() val timeValidator = TimeValidator(timeRepository, reservationFinder) context("validateIsAlreadyExists") { val startAt = LocalTime.now() test("같은 이메일을 가진 회원이 있으면 예외를 던진다.") { every { timeRepository.existsByStartAt(startAt) } returns true shouldThrow { timeValidator.validateIsAlreadyExists(startAt) }.also { it.errorCode shouldBe TimeErrorCode.TIME_DUPLICATED } } test("같은 이메일을 가진 회원이 없으면 종료한다.") { every { timeRepository.existsByStartAt(startAt) } returns false shouldNotThrow { timeValidator.validateIsAlreadyExists(startAt) } } } context("validateIsReserved") { val time: TimeEntity = TimeFixture.create(startAt = LocalTime.now()) test("해당 시간에 예약이 있으면 예외를 던진다.") { every { reservationFinder.isTimeReserved(time) } returns true shouldThrow { timeValidator.validateIsReserved(time) }.also { it.errorCode shouldBe TimeErrorCode.TIME_ALREADY_RESERVED } } test("해당 시간에 예약이 없으면 종료한다.") { every { reservationFinder.isTimeReserved(time) } returns false shouldNotThrow { timeValidator.validateIsReserved(time) } } } })