fix(home): 홈 추천 offset 계산 overflow를 방지한다

This commit is contained in:
2026-06-27 05:12:21 +09:00
parent c028aa4002
commit f99ed002b2
4 changed files with 9 additions and 9 deletions

View File

@@ -217,7 +217,7 @@ class HomeRecommendationFacade(
return memberContentPreferenceService.canViewAdultContent(member) return memberContentPreferenceService.canViewAdultContent(member)
} }
private fun Int.toOffset(size: Int): Int = this * size private fun Int.toOffset(size: Int): Long = this.toLong() * size
private fun <S, T> List<S>.toPage( private fun <S, T> List<S>.toPage(
page: Int, page: Int,

View File

@@ -21,7 +21,7 @@ class HomeOnAirLiveFacade(
fun getOnAirLives(member: Member, page: Int): HomeOnAirLivePageResponse { fun getOnAirLives(member: Member, page: Int): HomeOnAirLivePageResponse {
val normalizedPage = page.coerceIn(0, MAX_PAGE) val normalizedPage = page.coerceIn(0, MAX_PAGE)
val fetched = queryService.findLiveRecommendations( val fetched = queryService.findLiveRecommendations(
offset = normalizedPage * PAGE_SIZE, offset = normalizedPage.toLong() * PAGE_SIZE,
limit = PAGE_SIZE + 1, limit = PAGE_SIZE + 1,
memberId = member.id, memberId = member.id,
includeAdultLives = memberContentPreferenceService.canViewAdultContent(member) includeAdultLives = memberContentPreferenceService.canViewAdultContent(member)

View File

@@ -318,7 +318,7 @@ class HomeRecommendationControllerTest @Autowired constructor(
Mockito.`when`( Mockito.`when`(
failingQueryService.findRecentDebutCreators( failingQueryService.findRecentDebutCreators(
now = Mockito.any(LocalDateTime::class.java) ?: LocalDateTime.MIN, now = Mockito.any(LocalDateTime::class.java) ?: LocalDateTime.MIN,
offset = Mockito.eq(0), offset = Mockito.eq(0L),
limit = Mockito.eq(21), limit = Mockito.eq(21),
memberId = Mockito.eq(member.id), memberId = Mockito.eq(member.id),
includeAdultContents = Mockito.eq(false) includeAdultContents = Mockito.eq(false)
@@ -327,13 +327,13 @@ class HomeRecommendationControllerTest @Autowired constructor(
Mockito.`when`( Mockito.`when`(
failingQueryService.findFirstAudioContents( failingQueryService.findFirstAudioContents(
now = Mockito.any(LocalDateTime::class.java) ?: LocalDateTime.MIN, now = Mockito.any(LocalDateTime::class.java) ?: LocalDateTime.MIN,
offset = Mockito.eq(0), offset = Mockito.eq(0L),
limit = Mockito.eq(21), limit = Mockito.eq(21),
memberId = Mockito.eq(member.id), memberId = Mockito.eq(member.id),
includeAdultContents = Mockito.eq(false) includeAdultContents = Mockito.eq(false)
) )
).thenThrow(IllegalStateException("first audio page failed")) ).thenThrow(IllegalStateException("first audio page failed"))
Mockito.`when`(failingQueryService.findAiCharacterRecommendations(offset = 0, limit = 21)) Mockito.`when`(failingQueryService.findAiCharacterRecommendations(offset = 0L, limit = 21))
.thenThrow(IllegalStateException("ai page failed")) .thenThrow(IllegalStateException("ai page failed"))
assertThrows(IllegalStateException::class.java) { facade.getRecentDebutCreators(member, page = 0, size = 20) } assertThrows(IllegalStateException::class.java) { facade.getRecentDebutCreators(member, page = 0, size = 20) }

View File

@@ -22,7 +22,7 @@ class HomeOnAirLiveFacadeTest {
val member = createMember(100L) val member = createMember(100L)
Mockito.doReturn(true).`when`(preferenceService).canViewAdultContent(member) Mockito.doReturn(true).`when`(preferenceService).canViewAdultContent(member)
Mockito.doReturn((1L..21L).map { record(it) }).`when`(queryService).findLiveRecommendations( Mockito.doReturn((1L..21L).map { record(it) }).`when`(queryService).findLiveRecommendations(
eqValue(0), eqValue(0L),
eqValue(21), eqValue(21),
eqValue(member.id), eqValue(member.id),
eqValue(true) eqValue(true)
@@ -34,7 +34,7 @@ class HomeOnAirLiveFacadeTest {
assertEquals(20, response.size) assertEquals(20, response.size)
assertEquals(true, response.hasNext) assertEquals(true, response.hasNext)
assertEquals(20, response.items.size) assertEquals(20, response.items.size)
Mockito.verify(queryService).findLiveRecommendations(eqValue(0), eqValue(21), eqValue(member.id), eqValue(true)) Mockito.verify(queryService).findLiveRecommendations(eqValue(0L), eqValue(21), eqValue(member.id), eqValue(true))
} }
@Test @Test
@@ -43,7 +43,7 @@ class HomeOnAirLiveFacadeTest {
val member = createMember(100L) val member = createMember(100L)
Mockito.doReturn(false).`when`(preferenceService).canViewAdultContent(member) Mockito.doReturn(false).`when`(preferenceService).canViewAdultContent(member)
Mockito.doReturn(listOf(record(1L, creatorProfileImage = null))).`when`(queryService).findLiveRecommendations( Mockito.doReturn(listOf(record(1L, creatorProfileImage = null))).`when`(queryService).findLiveRecommendations(
eqValue(0), eqValue(0L),
eqValue(21), eqValue(21),
eqValue(member.id), eqValue(member.id),
eqValue(false) eqValue(false)
@@ -60,7 +60,7 @@ class HomeOnAirLiveFacadeTest {
val member = createMember(100L) val member = createMember(100L)
Mockito.doReturn(false).`when`(preferenceService).canViewAdultContent(member) Mockito.doReturn(false).`when`(preferenceService).canViewAdultContent(member)
Mockito.doReturn(listOf(record(1L, beginDateTime = LocalDateTime.of(2026, 6, 26, 12, 30)))).`when`(queryService) Mockito.doReturn(listOf(record(1L, beginDateTime = LocalDateTime.of(2026, 6, 26, 12, 30)))).`when`(queryService)
.findLiveRecommendations(eqValue(0), eqValue(21), eqValue(member.id), eqValue(false)) .findLiveRecommendations(eqValue(0L), eqValue(21), eqValue(member.id), eqValue(false))
val response = facade.getOnAirLives(member, page = 0) val response = facade.getOnAirLives(member, page = 0)