test #433
@@ -7,6 +7,7 @@ import kr.co.vividnext.sodalive.member.MemberRole
|
||||
import kr.co.vividnext.sodalive.member.block.BlockMember
|
||||
import kr.co.vividnext.sodalive.support.EmbeddedRedisInitializer
|
||||
import kr.co.vividnext.sodalive.v2.ranking.adapter.out.persistence.CreatorRankingSnapshot
|
||||
import kr.co.vividnext.sodalive.v2.ranking.domain.CreatorRankingScoreSpec
|
||||
import kr.co.vividnext.sodalive.v2.ranking.domain.CreatorRankingType
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
@@ -23,7 +24,13 @@ import org.springframework.transaction.annotation.Transactional
|
||||
import java.time.LocalDateTime
|
||||
import javax.persistence.EntityManager
|
||||
|
||||
@SpringBootTest(properties = ["cloud.aws.cloud-front.host=https://cdn.test"])
|
||||
@SpringBootTest(
|
||||
properties = [
|
||||
"cloud.aws.cloud-front.host=https://cdn.test",
|
||||
"spring.datasource.url=jdbc:h2:mem:creator-ranking-controller;" +
|
||||
"MODE=MySQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=VALUE;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"
|
||||
]
|
||||
)
|
||||
@AutoConfigureMockMvc
|
||||
@Transactional
|
||||
@ContextConfiguration(initializers = [EmbeddedRedisInitializer::class])
|
||||
@@ -33,13 +40,20 @@ class CreatorRankingControllerTest @Autowired constructor(
|
||||
private val entityManager: EntityManager
|
||||
) {
|
||||
@Test
|
||||
@DisplayName("크리에이터 랭킹 조회는 허용된 응답 필드만 반환하고 점수와 기간은 노출하지 않는다")
|
||||
fun shouldReturnCreatorRankingSchemaWithoutScoreAndPeriodFields() {
|
||||
@DisplayName("크리에이터 랭킹 API는 공개 응답 스키마만 노출하고 내부 스냅샷 필드를 숨긴다")
|
||||
fun shouldReturnOnlyPublicCreatorRankingSchemaThroughEndpoint() {
|
||||
val creatorOne = saveMember("creator-one", MemberRole.CREATOR)
|
||||
val creatorTwo = saveMember("creator-two", MemberRole.CREATOR)
|
||||
saveSnapshot(creatorId = creatorOne.id!!, nickname = "creator-one", profileImageUrl = "profile-one.png", rankNo = 2)
|
||||
saveSnapshot(creatorId = creatorTwo.id!!, nickname = "creator-two", profileImageUrl = "profile-two.png", rankNo = 1)
|
||||
saveSnapshot(
|
||||
creatorId = 1L,
|
||||
creatorId = creatorOne.id!!,
|
||||
nickname = "creator-one",
|
||||
profileImageUrl = "profile-one.png",
|
||||
finalScore = 100.0
|
||||
rankNo = 1,
|
||||
aggregationStartAtUtc = PREVIOUS_START,
|
||||
aggregationEndAtUtc = PREVIOUS_END,
|
||||
visibleFromAtUtc = PREVIOUS_VISIBLE
|
||||
)
|
||||
entityManager.flush()
|
||||
entityManager.clear()
|
||||
@@ -47,23 +61,33 @@ class CreatorRankingControllerTest @Autowired constructor(
|
||||
mockMvc.perform(get("/api/v2/home/rankings/creators"))
|
||||
.andExpect(status().isOk)
|
||||
.andExpect(jsonPath("$.success").value(true))
|
||||
.andExpect(jsonPath("$.data.showRankChange").value(false))
|
||||
.andExpect(jsonPath("$.data.showRankChange").value(true))
|
||||
.andExpect(jsonPath("$.data.items[0].rank").value(1))
|
||||
.andExpect(jsonPath("$.data.items[0].rankChange").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.items[0].isNew").value(false))
|
||||
.andExpect(jsonPath("$.data.items[0].creatorId").value(1L))
|
||||
.andExpect(jsonPath("$.data.items[0].nickname").value("creator-one"))
|
||||
.andExpect(jsonPath("$.data.items[0].profileImageUrl").value("https://cdn.test/profile-one.png"))
|
||||
.andExpect(jsonPath("$.data.items[0].isNew").value(true))
|
||||
.andExpect(jsonPath("$.data.items[0].creatorId").value(creatorTwo.id))
|
||||
.andExpect(jsonPath("$.data.items[0].nickname").value("creator-two"))
|
||||
.andExpect(jsonPath("$.data.items[0].profileImageUrl").value("https://cdn.test/profile-two.png"))
|
||||
.andExpect(jsonPath("$.data.items[1].rank").value(2))
|
||||
.andExpect(jsonPath("$.data.items[1].rankChange").value(-1))
|
||||
.andExpect(jsonPath("$.data.items[1].isNew").value(false))
|
||||
.andExpect(jsonPath("$.data.items[1].creatorId").value(creatorOne.id))
|
||||
.andExpect(jsonPath("$.data.items[1].nickname").value("creator-one"))
|
||||
.andExpect(jsonPath("$.data.items[1].profileImageUrl").value("https://cdn.test/profile-one.png"))
|
||||
.andExpect(jsonPath("$.data.items[0].finalScore").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.items[0].aggregationStartAtUtc").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.items[0].aggregationEndAtUtc").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.aggregationStartAtUtc").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.aggregationEndAtUtc").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.items[0].rankNo").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.items[0].scorePolicyVersion").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.items[0].scoreDetailJson").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.fallback").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.finalScore").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.rankNo").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.scorePolicyVersion").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.scoreDetailJson").doesNotExist())
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("크리에이터 랭킹 조회는 비회원도 호출 가능하고 빈 랭킹을 성공 응답으로 반환한다")
|
||||
fun shouldReturnEmptyCreatorRankingsForAnonymous() {
|
||||
@DisplayName("크리에이터 랭킹 API는 비회원도 빈 랭킹을 성공 응답으로 조회할 수 있다")
|
||||
fun shouldReturnEmptySuccessForAnonymous() {
|
||||
mockMvc.perform(get("/api/v2/home/rankings/creators"))
|
||||
.andExpect(status().isOk)
|
||||
.andExpect(jsonPath("$.success").value(true))
|
||||
@@ -73,7 +97,7 @@ class CreatorRankingControllerTest @Autowired constructor(
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("크리에이터 랭킹 조회는 인증 회원 id를 전달해 차단 크리에이터 정보를 마스킹한다")
|
||||
@DisplayName("크리에이터 랭킹 API는 인증 회원과 차단 관계인 크리에이터 정보를 마스킹한다")
|
||||
fun shouldMaskBlockedCreatorForAuthenticatedMember() {
|
||||
val viewer = saveMember("ranking-viewer", MemberRole.USER)
|
||||
val blockedCreator = saveMember("blocked-creator", MemberRole.CREATOR)
|
||||
@@ -81,7 +105,7 @@ class CreatorRankingControllerTest @Autowired constructor(
|
||||
creatorId = blockedCreator.id!!,
|
||||
nickname = blockedCreator.nickname,
|
||||
profileImageUrl = "blocked-profile.png",
|
||||
finalScore = 100.0
|
||||
rankNo = 1
|
||||
)
|
||||
saveBlock(member = viewer, blockedMember = blockedCreator)
|
||||
entityManager.flush()
|
||||
@@ -97,6 +121,11 @@ class CreatorRankingControllerTest @Autowired constructor(
|
||||
.andExpect(jsonPath("$.data.items[0].creatorId").value(0L))
|
||||
.andExpect(jsonPath("$.data.items[0].nickname").value(""))
|
||||
.andExpect(jsonPath("$.data.items[0].profileImageUrl").value("https://cdn.test/profile/default-profile.png"))
|
||||
.andExpect(jsonPath("$.data.items[0].finalScore").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.items[0].rankNo").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.items[0].scorePolicyVersion").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.items[0].scoreDetailJson").doesNotExist())
|
||||
.andExpect(jsonPath("$.data.fallback").doesNotExist())
|
||||
}
|
||||
|
||||
private fun saveMember(seed: String, role: MemberRole): Member {
|
||||
@@ -123,32 +152,34 @@ class CreatorRankingControllerTest @Autowired constructor(
|
||||
creatorId: Long,
|
||||
nickname: String,
|
||||
profileImageUrl: String?,
|
||||
finalScore: Double
|
||||
rankNo: Int,
|
||||
aggregationStartAtUtc: LocalDateTime = START,
|
||||
aggregationEndAtUtc: LocalDateTime = END,
|
||||
visibleFromAtUtc: LocalDateTime = VISIBLE
|
||||
) {
|
||||
entityManager.persist(
|
||||
CreatorRankingSnapshot(
|
||||
rankingType = CreatorRankingType.WEEKLY,
|
||||
aggregationStartAtUtc = LocalDateTime.of(2026, 5, 31, 15, 0, 0),
|
||||
aggregationEndAtUtc = LocalDateTime.of(2026, 6, 7, 15, 0, 0),
|
||||
visibleFromAtUtc = LocalDateTime.of(2026, 6, 8, 0, 0, 0),
|
||||
aggregationStartAtUtc = aggregationStartAtUtc,
|
||||
aggregationEndAtUtc = aggregationEndAtUtc,
|
||||
visibleFromAtUtc = visibleFromAtUtc,
|
||||
creatorId = creatorId,
|
||||
nickname = nickname,
|
||||
profileImageUrl = profileImageUrl,
|
||||
finalScore = finalScore,
|
||||
contentLiveScore = 0.0,
|
||||
engagementScore = 0.0,
|
||||
supportScore = 0.0,
|
||||
fanLoyaltyScore = 0.0,
|
||||
liveCanAmount = 0,
|
||||
contentPurchaseCanAmount = 0,
|
||||
contentLikeCount = 0,
|
||||
contentCommentCount = 0,
|
||||
channelDonationCanAmount = 0,
|
||||
channelDonationCount = 0,
|
||||
fanTalkCount = 0,
|
||||
finalFollowerCount = 0,
|
||||
followIncrease = 0
|
||||
rankNo = rankNo,
|
||||
finalScore = (100 - rankNo).toDouble(),
|
||||
scorePolicyVersion = CreatorRankingScoreSpec.SCORE_POLICY_VERSION,
|
||||
scoreDetailJson = "{}"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val PREVIOUS_START = LocalDateTime.of(2026, 5, 24, 15, 0)
|
||||
private val PREVIOUS_END = LocalDateTime.of(2026, 5, 31, 15, 0)
|
||||
private val PREVIOUS_VISIBLE = LocalDateTime.of(2026, 6, 1, 0, 0)
|
||||
private val START = LocalDateTime.of(2026, 5, 31, 15, 0)
|
||||
private val END = LocalDateTime.of(2026, 6, 7, 15, 0)
|
||||
private val VISIBLE = LocalDateTime.of(2026, 6, 8, 0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user