test: 가장 많이 예약된 테마 ID 조회 API 테스트

This commit is contained in:
이상진 2025-09-13 15:40:42 +09:00
parent 6eecd145cc
commit 905c4b7019

View File

@ -6,7 +6,10 @@ import org.springframework.data.repository.findByIdOrNull
import org.springframework.http.HttpMethod
import org.springframework.http.HttpStatus
import roomescape.auth.exception.AuthErrorCode
import roomescape.common.config.next
import roomescape.common.exception.CommonErrorCode
import roomescape.common.util.DateUtils
import roomescape.member.infrastructure.persistence.UserEntity
import roomescape.payment.exception.PaymentErrorCode
import roomescape.payment.infrastructure.common.BankCode
import roomescape.payment.infrastructure.common.CardIssuerCode
@ -17,18 +20,22 @@ import roomescape.reservation.infrastructure.persistence.CanceledReservationRepo
import roomescape.reservation.infrastructure.persistence.ReservationEntity
import roomescape.reservation.infrastructure.persistence.ReservationRepository
import roomescape.reservation.infrastructure.persistence.ReservationStatus
import roomescape.reservation.web.MostReservedThemeIdListResponse
import roomescape.reservation.web.ReservationCancelRequest
import roomescape.schedule.infrastructure.persistence.ScheduleEntity
import roomescape.schedule.infrastructure.persistence.ScheduleRepository
import roomescape.schedule.infrastructure.persistence.ScheduleStatus
import roomescape.theme.infrastructure.persistence.ThemeEntity
import roomescape.supports.*
import roomescape.theme.infrastructure.persistence.ThemeEntity
import roomescape.theme.infrastructure.persistence.ThemeRepository
import roomescape.theme.web.toEntity
import java.time.LocalDate
import java.time.LocalTime
class ReservationApiTest(
private val reservationRepository: ReservationRepository,
private val canceledReservationRepository: CanceledReservationRepository,
private val themeRepository: ThemeRepository,
private val scheduleRepository: ScheduleRepository,
private val paymentDetailRepository: PaymentDetailRepository,
) : FunSpecSpringbootTest() {
@ -299,7 +306,8 @@ class ReservationApiTest(
reserverToken = authUtil.defaultUserLogin(),
)
val otherUserToken = authUtil.userLogin(UserFixture.createUser(email = "test@test.com", phone="01011111111"))
val otherUserToken =
authUtil.userLogin(UserFixture.createUser(email = "test@test.com", phone = "01011111111"))
runExceptionTest(
token = otherUserToken,
@ -602,6 +610,24 @@ class ReservationApiTest(
)
}
}
context("가장 많이 예약된 테마 ID를 조회한다.") {
test("정상 응답") {
val expectedResult: MostReservedThemeIdListResponse = initializeForPopularThemeTest()
runTest(
on = {
get("/reservations/popular-themes?count=10")
},
expect = {
statusCode(HttpStatus.OK.value())
}
).also {
val result: List<Long> = it.extract().path("data.themeIds")
result shouldBe expectedResult.themeIds
}
}
}
}
fun runDetailRetrieveTest(
@ -621,4 +647,92 @@ class ReservationApiTest(
it.extract().path<Long>("data.user.id") shouldBe reservation.userId
}.extract().path("data.payment")
}
private fun initializeForPopularThemeTest(): MostReservedThemeIdListResponse {
val user: UserEntity = authUtil.defaultUser()
val themeIds: List<Long> = (1..5).map {
themeRepository.save(
ThemeFixture.createRequest.copy(name = "theme-$it").toEntity(id = tsidFactory.next())
).id
}
// 첫 번째 테마: 유효한 2개 예약
(1L..2L).forEach {
createScheduleAndReservation(
date = DateUtils.getSundayOfPreviousWeek(LocalDate.now()).plusDays(it),
themeId = themeIds[0],
userId = user.id,
)
}
// 두 번째 테마: 유효한 1개 예약
createScheduleAndReservation(
date = DateUtils.getSundayOfPreviousWeek(LocalDate.now()),
themeId = themeIds[1],
userId = user.id,
)
// 세 번째 테마: 유효한 3개 예약
(1L..3L).forEach {
createScheduleAndReservation(
date = DateUtils.getSundayOfPreviousWeek(LocalDate.now()).plusDays(it),
themeId = themeIds[2],
userId = user.id,
)
}
// 네 번째 테마: Pending 상태인 3개 예약 -> 집계되지 않음.
(1L..3L).forEach {
createScheduleAndReservation(
date = DateUtils.getSundayOfPreviousWeek(LocalDate.now()).plusDays(it),
themeId = themeIds[3],
userId = user.id,
isPending = true
)
}
// 다섯 번째 테마: 이번주의 확정 예약 -> 집계되지 않음.
(1L..3L).forEach { i ->
val thisMonday = DateUtils.getSundayOfPreviousWeek(LocalDate.now()).plusDays(8)
createScheduleAndReservation(
date = thisMonday.plusDays(i),
themeId = themeIds[4],
userId = user.id,
)
}
// 조회 예상 결과: 세번째, 첫번째, 두번째 테마 순서
return MostReservedThemeIdListResponse(listOf(themeIds[2], themeIds[0], themeIds[1]))
}
private fun createScheduleAndReservation(
date: LocalDate,
themeId: Long,
userId: Long,
isPending: Boolean = false
) {
val schedule = ScheduleEntity(
id = tsidFactory.next(),
date = date,
time = LocalTime.now(),
themeId = themeId,
status = if (isPending) ScheduleStatus.HOLD else ScheduleStatus.RESERVED
).also {
scheduleRepository.save(it)
}
ReservationEntity(
id = tsidFactory.next(),
userId = userId,
scheduleId = schedule.id,
reserverName = "이상돌",
reserverContact = "01012345678",
participantCount = 4,
requirement = "잘부탁드려요!",
status = if (isPending) ReservationStatus.PENDING else ReservationStatus.CONFIRMED,
).also {
reservationRepository.save(it)
}
}
}