package roomescape.reservation.business 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 org.springframework.data.repository.findByIdOrNull import org.springframework.http.HttpStatus import roomescape.common.exception.ErrorType import roomescape.common.exception.RoomescapeException import roomescape.reservation.infrastructure.persistence.ReservationRepository import roomescape.reservation.infrastructure.persistence.ReservationTimeRepository import roomescape.reservation.web.ReservationTimeRequest import roomescape.util.ReservationTimeFixture import java.time.LocalTime class ReservationTimeServiceTest : FunSpec({ val reservationTimeRepository: ReservationTimeRepository = mockk() val reservationRepository: ReservationRepository = mockk() val reservationTimeService = ReservationTimeService( reservationTimeRepository = reservationTimeRepository, reservationRepository = reservationRepository ) context("findTimeById") { test("시간을 찾을 수 없으면 400 에러를 던진다.") { val id = 1L // Mocking the behavior of reservationTimeRepository.findByIdOrNull every { reservationTimeRepository.findByIdOrNull(id) } returns null shouldThrow { reservationTimeService.findTimeById(id) }.apply { errorType shouldBe ErrorType.RESERVATION_TIME_NOT_FOUND httpStatus shouldBe HttpStatus.BAD_REQUEST } } } context("addTime") { test("중복된 시간이 있으면 409 에러를 던진다.") { val request = ReservationTimeRequest(startAt = LocalTime.of(10, 0)) // Mocking the behavior of reservationTimeRepository.findByStartAt every { reservationTimeRepository.existsByStartAt(request.startAt) } returns true shouldThrow { reservationTimeService.addTime(request) }.apply { errorType shouldBe ErrorType.TIME_DUPLICATED httpStatus shouldBe HttpStatus.CONFLICT } } } context("removeTimeById") { test("시간을 찾을 수 없으면 400 에러를 던진다.") { val id = 1L // Mocking the behavior of reservationTimeRepository.findByIdOrNull every { reservationTimeRepository.findByIdOrNull(id) } returns null shouldThrow { reservationTimeService.removeTimeById(id) }.apply { errorType shouldBe ErrorType.RESERVATION_TIME_NOT_FOUND httpStatus shouldBe HttpStatus.BAD_REQUEST } } test("예약이 있는 시간이면 409 에러를 던진다.") { val id = 1L val reservationTime = ReservationTimeFixture.create() // Mocking the behavior of reservationTimeRepository.findByIdOrNull every { reservationTimeRepository.findByIdOrNull(id) } returns reservationTime // Mocking the behavior of reservationRepository.findByReservationTime every { reservationRepository.findByReservationTime(reservationTime) } returns listOf(mockk()) shouldThrow { reservationTimeService.removeTimeById(id) }.apply { errorType shouldBe ErrorType.TIME_IS_USED_CONFLICT httpStatus shouldBe HttpStatus.CONFLICT } } } })