feat(content-preference): 콘텐츠 조회 설정 서버 저장 전환을 반영한다

This commit is contained in:
2026-03-27 13:33:51 +09:00
parent 1ba3cb8a40
commit a87bd147dc
75 changed files with 3593 additions and 301 deletions

View File

@@ -3,6 +3,8 @@ package kr.co.vividnext.sodalive.live.recommend
import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.member.auth.Auth
import kr.co.vividnext.sodalive.member.block.BlockMemberRepository
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreferenceService
import kr.co.vividnext.sodalive.member.contentpreference.ViewerContentPreference
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
@@ -11,13 +13,22 @@ import org.mockito.Mockito
class LiveRecommendServiceTest {
private lateinit var repository: LiveRecommendRepository
private lateinit var blockMemberRepository: BlockMemberRepository
private lateinit var memberContentPreferenceService: MemberContentPreferenceService
private lateinit var liveRecommendCacheService: LiveRecommendCacheService
private lateinit var service: LiveRecommendService
@BeforeEach
fun setup() {
repository = Mockito.mock(LiveRecommendRepository::class.java)
blockMemberRepository = Mockito.mock(BlockMemberRepository::class.java)
service = LiveRecommendService(repository, blockMemberRepository)
memberContentPreferenceService = Mockito.mock(MemberContentPreferenceService::class.java)
liveRecommendCacheService = Mockito.mock(LiveRecommendCacheService::class.java)
service = LiveRecommendService(
repository = repository,
blockMemberRepository = blockMemberRepository,
memberContentPreferenceService = memberContentPreferenceService,
liveRecommendCacheService = liveRecommendCacheService
)
}
@Test
@@ -39,24 +50,35 @@ class LiveRecommendServiceTest {
auth.member = member
val expected = listOf(GetRecommendLiveResponse(imageUrl = "https://cdn.test/recommend.png", creatorId = 77L))
Mockito.`when`(repository.getRecommendLive(memberId = member.id, isAdult = true)).thenReturn(expected)
Mockito.`when`(memberContentPreferenceService.getStoredPreference(member)).thenReturn(
ViewerContentPreference(
countryCode = "KR",
isAdultContentVisible = true,
contentType = kr.co.vividnext.sodalive.content.ContentType.ALL,
isAdult = true
)
)
Mockito.`when`(liveRecommendCacheService.getRecommendLive(memberId = member.id, isAdult = true)).thenReturn(expected)
val result = service.getRecommendLive(member)
assertEquals(expected, result)
Mockito.verify(repository).getRecommendLive(memberId = member.id, isAdult = true)
Mockito.verify(liveRecommendCacheService).getRecommendLive(memberId = member.id, isAdult = true)
Mockito.verifyNoInteractions(repository)
Mockito.verifyNoInteractions(blockMemberRepository)
}
@Test
fun shouldDelegateToRepositoryAsGuestWhenMemberIsNull() {
val expected = listOf(GetRecommendLiveResponse(imageUrl = "https://cdn.test/recommend-guest.png", creatorId = 88L))
Mockito.`when`(repository.getRecommendLive(memberId = null, isAdult = false)).thenReturn(expected)
Mockito.`when`(liveRecommendCacheService.getRecommendLive(memberId = null, isAdult = false)).thenReturn(expected)
val result = service.getRecommendLive(null)
assertEquals(expected, result)
Mockito.verify(repository).getRecommendLive(memberId = null, isAdult = false)
Mockito.verify(liveRecommendCacheService).getRecommendLive(memberId = null, isAdult = false)
Mockito.verifyNoInteractions(repository)
Mockito.verifyNoInteractions(blockMemberRepository)
Mockito.verifyNoInteractions(memberContentPreferenceService)
}
}

View File

@@ -0,0 +1,87 @@
package kr.co.vividnext.sodalive.live.tag
import com.fasterxml.jackson.databind.ObjectMapper
import kr.co.vividnext.sodalive.aws.s3.S3Uploader
import kr.co.vividnext.sodalive.content.ContentType
import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.member.MemberRole
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreferenceService
import kr.co.vividnext.sodalive.member.contentpreference.ViewerContentPreference
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.mockito.Mockito
class LiveTagServiceTest {
private lateinit var repository: LiveTagRepository
private lateinit var memberContentPreferenceService: MemberContentPreferenceService
private lateinit var service: LiveTagService
@BeforeEach
fun setup() {
repository = mock()
memberContentPreferenceService = mock()
service = LiveTagService(
repository = repository,
memberContentPreferenceService = memberContentPreferenceService,
objectMapper = ObjectMapper(),
s3Uploader = mock<S3Uploader>(),
coverImageBucket = "bucket",
cloudFrontHost = "https://cdn.test"
)
}
@Test
@DisplayName("일반 사용자는 저장된 성인 설정값으로 라이브 태그 필터를 적용한다")
fun shouldApplyStoredPreferenceForNonAdminMember() {
val member = createMember(id = 1L, role = MemberRole.USER)
val expected = listOf(GetLiveTagResponse(1L, "일반", "https://cdn.test/live1.png", false))
Mockito.`when`(memberContentPreferenceService.getStoredPreference(member)).thenReturn(
ViewerContentPreference(
countryCode = "KR",
isAdultContentVisible = false,
contentType = ContentType.ALL,
isAdult = false
)
)
Mockito.`when`(repository.getTags(isAdult = false, cloudFrontHost = "https://cdn.test")).thenReturn(expected)
val actual = service.getTags(member)
assertEquals(expected, actual)
Mockito.verify(repository).getTags(isAdult = false, cloudFrontHost = "https://cdn.test")
}
@Test
@DisplayName("관리자는 저장 설정과 무관하게 성인 태그를 포함해 조회한다")
fun shouldAllowAdultTagsForAdmin() {
val admin = createMember(id = 2L, role = MemberRole.ADMIN)
val expected = listOf(GetLiveTagResponse(2L, "성인", "https://cdn.test/live2.png", true))
Mockito.`when`(repository.getTags(isAdult = true, cloudFrontHost = "https://cdn.test")).thenReturn(expected)
val actual = service.getTags(admin)
assertEquals(expected, actual)
Mockito.verify(repository).getTags(isAdult = true, cloudFrontHost = "https://cdn.test")
Mockito.verifyNoInteractions(memberContentPreferenceService)
}
private fun createMember(id: Long, role: MemberRole): Member {
val member = Member(
email = "member$id@test.com",
password = "password",
nickname = "member$id",
role = role
)
member.id = id
return member
}
private inline fun <reified T> mock(): T {
return Mockito.mock(T::class.java)
}
}