test: 인기 테마 관련 테스트 수정

This commit is contained in:
이상진 2025-09-27 15:19:59 +09:00
parent a4d28322fb
commit 23ea8d13ea
2 changed files with 103 additions and 123 deletions

View File

@ -7,9 +7,7 @@ import org.springframework.data.repository.findByIdOrNull
import org.springframework.http.HttpMethod import org.springframework.http.HttpMethod
import org.springframework.http.HttpStatus import org.springframework.http.HttpStatus
import roomescape.auth.exception.AuthErrorCode import roomescape.auth.exception.AuthErrorCode
import roomescape.common.config.next
import roomescape.common.exception.CommonErrorCode import roomescape.common.exception.CommonErrorCode
import roomescape.common.util.DateUtils
import roomescape.payment.infrastructure.common.BankCode import roomescape.payment.infrastructure.common.BankCode
import roomescape.payment.infrastructure.common.CardIssuerCode import roomescape.payment.infrastructure.common.CardIssuerCode
import roomescape.payment.infrastructure.common.EasyPayCompanyCode import roomescape.payment.infrastructure.common.EasyPayCompanyCode
@ -19,7 +17,6 @@ import roomescape.reservation.infrastructure.persistence.CanceledReservationRepo
import roomescape.reservation.infrastructure.persistence.ReservationEntity import roomescape.reservation.infrastructure.persistence.ReservationEntity
import roomescape.reservation.infrastructure.persistence.ReservationRepository import roomescape.reservation.infrastructure.persistence.ReservationRepository
import roomescape.reservation.infrastructure.persistence.ReservationStatus import roomescape.reservation.infrastructure.persistence.ReservationStatus
import roomescape.reservation.web.MostReservedThemeIdListResponse
import roomescape.reservation.web.ReservationCancelRequest import roomescape.reservation.web.ReservationCancelRequest
import roomescape.reservation.web.ReservationOverviewResponse import roomescape.reservation.web.ReservationOverviewResponse
import roomescape.schedule.infrastructure.persistence.ScheduleEntity import roomescape.schedule.infrastructure.persistence.ScheduleEntity
@ -28,8 +25,6 @@ import roomescape.schedule.infrastructure.persistence.ScheduleStatus
import roomescape.supports.* import roomescape.supports.*
import roomescape.theme.infrastructure.persistence.ThemeEntity import roomescape.theme.infrastructure.persistence.ThemeEntity
import roomescape.theme.infrastructure.persistence.ThemeRepository import roomescape.theme.infrastructure.persistence.ThemeRepository
import roomescape.theme.web.toEntity
import roomescape.user.infrastructure.persistence.UserEntity
import java.time.LocalDate import java.time.LocalDate
import java.time.LocalTime import java.time.LocalTime
@ -566,24 +561,6 @@ 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( fun runDetailRetrieveTest(
@ -605,76 +582,4 @@ class ReservationApiTest(
it.extract().path<Long>("data.user.id") shouldBe reservation.userId it.extract().path<Long>("data.user.id") shouldBe reservation.userId
}.extract().path("data.payment") }.extract().path("data.payment")
} }
private fun initializeForPopularThemeTest(): MostReservedThemeIdListResponse {
val user: UserEntity = testAuthUtil.defaultUser()
val themeIds: List<Long> = (1..5).map {
themeRepository.save(ThemeFixture.createRequest.copy().toEntity(id = tsidFactory.next())).id
}
val store = dummyInitializer.createStore()
// 첫 번째 테마: 유효한 2개 예약
(1L..2L).forEach {
dummyInitializer.createConfirmReservation(
user = user,
storeId = store.id,
scheduleRequest = ScheduleFixture.createRequest.copy(
date = DateUtils.getSundayOfPreviousWeek(LocalDate.now()).plusDays(it),
themeId = themeIds[0],
)
)
}
// 두 번째 테마: 유효한 1개 예약
dummyInitializer.createConfirmReservation(
user = user,
storeId = store.id,
scheduleRequest = ScheduleFixture.createRequest.copy(
date = DateUtils.getSundayOfPreviousWeek(LocalDate.now()),
themeId = themeIds[1],
)
)
// 세 번째 테마: 유효한 3개 예약
(1L..3L).forEach {
dummyInitializer.createConfirmReservation(
user = user,
storeId = store.id,
scheduleRequest = ScheduleFixture.createRequest.copy(
date = DateUtils.getSundayOfPreviousWeek(LocalDate.now()).plusDays(it),
themeId = themeIds[2],
)
)
}
// 네 번째 테마: Pending 상태인 3개 예약 -> 집계되지 않음.
(1L..3L).forEach {
dummyInitializer.createPendingReservation(
user = user,
storeId = store.id,
scheduleRequest = ScheduleFixture.createRequest.copy(
date = DateUtils.getSundayOfPreviousWeek(LocalDate.now()).plusDays(it),
themeId = themeIds[3],
)
)
}
// 다섯 번째 테마: 이번주의 확정 예약 -> 집계되지 않음.
(1L..3L).forEach { i ->
val thisMonday = DateUtils.getSundayOfPreviousWeek(LocalDate.now()).plusDays(8)
dummyInitializer.createConfirmReservation(
user = user,
storeId = store.id,
scheduleRequest = ScheduleFixture.createRequest.copy(
date = thisMonday.plusDays(i),
themeId = themeIds[4],
)
)
}
// 조회 예상 결과: 세번째, 첫번째, 두번째 테마 순서
return MostReservedThemeIdListResponse(listOf(themeIds[2], themeIds[0], themeIds[1]))
}
} }

View File

@ -1,41 +1,24 @@
package roomescape.theme package roomescape.theme
import io.kotest.matchers.collections.shouldContainInOrder
import io.kotest.matchers.collections.shouldHaveSize
import org.hamcrest.CoreMatchers.equalTo import org.hamcrest.CoreMatchers.equalTo
import org.springframework.http.HttpMethod import org.springframework.http.HttpMethod
import org.springframework.http.HttpStatus import org.springframework.http.HttpStatus
import roomescape.common.config.next
import roomescape.common.util.DateUtils
import roomescape.supports.* import roomescape.supports.*
import roomescape.theme.exception.ThemeErrorCode import roomescape.theme.exception.ThemeErrorCode
import roomescape.theme.infrastructure.persistence.ThemeEntity import roomescape.theme.infrastructure.persistence.ThemeEntity
import roomescape.theme.web.ThemeIdListRequest import roomescape.theme.infrastructure.persistence.ThemeRepository
import roomescape.theme.web.toEntity
import roomescape.user.infrastructure.persistence.UserEntity
import java.time.LocalDate
class ThemeApiTest : FunSpecSpringbootTest() { class ThemeApiTest(
private val themeRepository: ThemeRepository
) : FunSpecSpringbootTest() {
init { init {
context("입력된 모든 ID에 대한 테마를 조회한다.") {
test("정상 응답 + 없는 테마가 있으면 생략한다.") {
val themeIds: List<Long> = initialize("목록 조회를 위한 3개의 테마 생성 및 일부 존재하지 않는 ID 추가") {
val themeIds = mutableListOf(INVALID_PK)
(1..3).forEach { _ ->
themeIds.add(dummyInitializer.createTheme().id)
}
themeIds
}
runTest(
using = {
body(ThemeIdListRequest(themeIds))
},
on = {
post("/themes/batch")
},
expect = {
statusCode(HttpStatus.OK.value())
body("data.themes.size()", equalTo(themeIds.filter { it != INVALID_PK }.size))
}
)
}
}
context("ID로 테마 정보를 조회한다.") { context("ID로 테마 정보를 조회한다.") {
test("정상 응답") { test("정상 응답") {
val createdTheme: ThemeEntity = initialize("조회를 위한 테마 생성") { val createdTheme: ThemeEntity = initialize("조회를 위한 테마 생성") {
@ -68,5 +51,97 @@ class ThemeApiTest : FunSpecSpringbootTest() {
) )
} }
} }
context("인기 테마를 조회한다.") {
test("정상 응답") {
val expectedResult: List<Long> = initializeForPopularThemeTest()
runTest(
on = {
get("/themes/most-reserved?count=10")
},
expect = {
statusCode(HttpStatus.OK.value())
}
).also { res ->
val response: List<LinkedHashMap<String, Any>> = res.extract().path("data.themes")
response shouldHaveSize expectedResult.size
response.map { it["id"] as Long }.shouldContainInOrder(expectedResult)
}
}
}
}
private fun initializeForPopularThemeTest(): List<Long> {
val user: UserEntity = testAuthUtil.defaultUser()
val themeIds: List<Long> = (1..5).map {
themeRepository.save(ThemeFixture.createRequest.copy().toEntity(id = tsidFactory.next())).id
}
val store = dummyInitializer.createStore()
// 첫 번째 테마: 유효한 2개 예약
(1L..2L).forEach {
dummyInitializer.createConfirmReservation(
user = user,
storeId = store.id,
scheduleRequest = ScheduleFixture.createRequest.copy(
date = DateUtils.getSundayOfPreviousWeek(LocalDate.now()).plusDays(it),
themeId = themeIds[0],
)
)
}
// 두 번째 테마: 유효한 1개 예약
dummyInitializer.createConfirmReservation(
user = user,
storeId = store.id,
scheduleRequest = ScheduleFixture.createRequest.copy(
date = DateUtils.getSundayOfPreviousWeek(LocalDate.now()),
themeId = themeIds[1],
)
)
// 세 번째 테마: 유효한 3개 예약
(1L..3L).forEach {
dummyInitializer.createConfirmReservation(
user = user,
storeId = store.id,
scheduleRequest = ScheduleFixture.createRequest.copy(
date = DateUtils.getSundayOfPreviousWeek(LocalDate.now()).plusDays(it),
themeId = themeIds[2],
)
)
}
// 네 번째 테마: Pending 상태인 3개 예약 -> 집계되지 않음.
(1L..3L).forEach {
dummyInitializer.createPendingReservation(
user = user,
storeId = store.id,
scheduleRequest = ScheduleFixture.createRequest.copy(
date = DateUtils.getSundayOfPreviousWeek(LocalDate.now()).plusDays(it),
themeId = themeIds[3],
)
)
}
// 다섯 번째 테마: 이번주의 확정 예약 -> 집계되지 않음.
(1L..3L).forEach { i ->
val thisMonday = DateUtils.getSundayOfPreviousWeek(LocalDate.now()).plusDays(8)
dummyInitializer.createConfirmReservation(
user = user,
storeId = store.id,
scheduleRequest = ScheduleFixture.createRequest.copy(
date = thisMonday.plusDays(i),
themeId = themeIds[4],
)
)
}
// 조회 예상 결과: 세번째, 첫번째, 두번째 테마 순서
return listOf(themeIds[2], themeIds[0], themeIds[1])
} }
} }