package roomescape.reservation.business import io.kotest.assertions.assertSoftly import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.collections.shouldHaveSize import io.kotest.matchers.shouldBe import io.mockk.every import io.mockk.mockk import roomescape.reservation.exception.ReservationErrorCode import roomescape.reservation.exception.ReservationException import roomescape.reservation.implement.ReservationFinder import roomescape.reservation.infrastructure.persistence.ReservationStatus import roomescape.reservation.web.MyReservationRetrieveResponse import roomescape.util.MemberFixture import roomescape.util.ReservationFixture import roomescape.util.ThemeFixture import java.time.LocalDate class ReservationQueryServiceTest : FunSpec({ val reservationFinder: ReservationFinder = mockk() val reservationFindService = ReservationFindService(reservationFinder) context("findReservations") { test("정상 응답") { val confirmedReservations = listOf( ReservationFixture.create(status = ReservationStatus.CONFIRMED), ReservationFixture.create(status = ReservationStatus.CONFIRMED_PAYMENT_REQUIRED) ) every { reservationFinder.findAllByStatuses(*ReservationStatus.confirmedStatus()) } returns confirmedReservations val response = reservationFindService.findReservations() assertSoftly(response.reservations) { this shouldHaveSize 2 } } } context("findAllWaiting") { test("정상 응답") { val waitingReservations = listOf( ReservationFixture.create(status = ReservationStatus.WAITING), ReservationFixture.create(status = ReservationStatus.WAITING) ) every { reservationFinder.findAllByStatuses(ReservationStatus.WAITING) } returns waitingReservations val response = reservationFindService.findAllWaiting() assertSoftly(response.reservations) { this shouldHaveSize 2 } } } context("findReservationsByMemberId") { val memberId = 1L test("정상 응답") { val myReservations = listOf(mockk(), mockk()) every { reservationFinder.findAllByMemberId(memberId) } returns myReservations val response = reservationFindService.findReservationsByMemberId(memberId) response.reservations shouldHaveSize 2 } } context("searchReservations") { val themeId = 1L val memberId = 1L val startFrom = LocalDate.now() val endAt = LocalDate.now().plusDays(1) test("정상 응답") { val searchedReservations = listOf( ReservationFixture.create( theme = ThemeFixture.create(themeId), member = MemberFixture.create(memberId), date = startFrom ) ) every { reservationFinder.searchReservations(themeId, memberId, startFrom, endAt) } returns searchedReservations val response = reservationFindService.searchReservations(themeId, memberId, startFrom, endAt) assertSoftly(response.reservations) { this shouldHaveSize 1 this[0].theme.id shouldBe themeId this[0].member.id shouldBe memberId this[0].date shouldBe startFrom } } test("종료 날짜가 시작 날짜 이전이면 예외 응답") { val invalidEndAt = startFrom.minusDays(1) every { reservationFinder.searchReservations(themeId, memberId, startFrom, invalidEndAt) } throws ReservationException(ReservationErrorCode.INVALID_SEARCH_DATE_RANGE) shouldThrow { reservationFindService.searchReservations(themeId, memberId, startFrom, invalidEndAt) }.also { it.errorCode shouldBe ReservationErrorCode.INVALID_SEARCH_DATE_RANGE } } } })