fix(comment-nickname): deleted_ 로 시작하는 닉네임 접두사 노출을 제거한다
This commit is contained in:
22
docs/20260220_삭제닉네임접두사표시정리.md
Normal file
22
docs/20260220_삭제닉네임접두사표시정리.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# 20260220 삭제 닉네임 접두사 표시 정리
|
||||
|
||||
## 구현 계획
|
||||
- [x] 콘텐츠 댓글, 팬톡 응원, 커뮤니티 댓글의 닉네임 표시 흐름(조회/매핑/응답 DTO)을 각각 식별한다.
|
||||
- [x] 닉네임이 `deleted_`로 시작하는지 판별하고 표시 시 접두사만 제거하는 공통 처리 지점을 설계한다.
|
||||
- [x] 콘텐츠 댓글 표시 로직에 `deleted_` 접두사 제거 규칙을 적용한다.
|
||||
- [x] 팬톡 응원 표시 로직에 `deleted_` 접두사 제거 규칙을 적용한다.
|
||||
- [x] 커뮤니티 댓글 표시 로직에 `deleted_` 접두사 제거 규칙을 적용한다.
|
||||
- [x] `deleted_` 미포함 닉네임, `deleted_` 포함 닉네임, 접두사만 존재하는 경계 케이스를 기준으로 테스트 케이스를 추가/보강한다.
|
||||
|
||||
## 검증 계획
|
||||
- [x] 닉네임 표시에 영향이 있는 테스트를 우선 실행하고 실패 시 원인을 보정한다.
|
||||
- [x] `./gradlew test`를 실행해 회귀 여부를 확인한다.
|
||||
- [x] 필요 시 `./gradlew ktlintCheck`로 스타일 규칙 위반 여부를 확인한다.
|
||||
- [x] `./gradlew build`를 실행해 전체 빌드 성공을 확인한다.
|
||||
|
||||
## 검증 기록
|
||||
- [x] 작업 완료 후 검증 결과를 기록한다.
|
||||
|
||||
- 무엇을: `String.removeDeletedNicknamePrefix()` 공통 확장 함수를 추가하고, 콘텐츠 댓글(`AudioContentCommentRepository`), 팬톡 응원(`ExplorerQueryRepository#getCheersList`), 커뮤니티 댓글(`CreatorCommunityCommentRepository`) 응답 닉네임에 동일 규칙을 적용했다.
|
||||
- 왜: 탈퇴/비활성 사용자 닉네임 저장 정책(`deleted_` 접두사 유지)과 화면 표시 정책(접두사 제거)을 분리해, 사용자에게는 일관된 표시값을 제공하기 위해서다.
|
||||
- 어떻게 검증했는지: `./gradlew test --tests "kr.co.vividnext.sodalive.extensions.StringExtensionsTest"`, `./gradlew test`, `./gradlew ktlintCheck`, `./gradlew build`를 실행해 모두 `BUILD SUCCESSFUL`을 확인했다. 또한 경계 케이스(`deleted_testUser`, `testUser`, `deleted_`) 단위 테스트를 추가해 기대 출력이 각각 `testUser`, `testUser`, `""`인지 검증했다.
|
||||
@@ -4,6 +4,7 @@ import com.querydsl.core.types.dsl.Expressions
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||
import kr.co.vividnext.sodalive.content.QAudioContent.audioContent
|
||||
import kr.co.vividnext.sodalive.content.comment.QAudioContentComment.audioContentComment
|
||||
import kr.co.vividnext.sodalive.extensions.removeDeletedNicknamePrefix
|
||||
import kr.co.vividnext.sodalive.fcm.PushTokenInfo
|
||||
import kr.co.vividnext.sodalive.fcm.QPushToken.pushToken
|
||||
import kr.co.vividnext.sodalive.fcm.QPushTokenInfo
|
||||
@@ -103,8 +104,10 @@ class AudioContentCommentQueryRepositoryImpl(
|
||||
.orderBy(audioContentComment.createdAt.desc())
|
||||
.fetch()
|
||||
.map {
|
||||
it.replyCount = commentReplyCountByAudioContentCommentId(it.id)
|
||||
it
|
||||
it.copy(
|
||||
nickname = it.nickname.removeDeletedNicknamePrefix(),
|
||||
replyCount = commentReplyCountByAudioContentCommentId(it.id)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,6 +190,9 @@ class AudioContentCommentQueryRepositoryImpl(
|
||||
.limit(limit.toLong())
|
||||
.orderBy(audioContentComment.createdAt.desc())
|
||||
.fetch()
|
||||
.map {
|
||||
it.copy(nickname = it.nickname.removeDeletedNicknamePrefix())
|
||||
}
|
||||
}
|
||||
|
||||
override fun findPushTokenByContentIdAndCommentParentIdMyMemberId(
|
||||
|
||||
@@ -19,6 +19,7 @@ import kr.co.vividnext.sodalive.explorer.profile.CreatorCheers
|
||||
import kr.co.vividnext.sodalive.explorer.profile.QChannelNotice.channelNotice
|
||||
import kr.co.vividnext.sodalive.explorer.profile.QCreatorCheers.creatorCheers
|
||||
import kr.co.vividnext.sodalive.explorer.profile.TimeDifferenceResult
|
||||
import kr.co.vividnext.sodalive.extensions.removeDeletedNicknamePrefix
|
||||
import kr.co.vividnext.sodalive.i18n.Lang
|
||||
import kr.co.vividnext.sodalive.i18n.LangContext
|
||||
import kr.co.vividnext.sodalive.i18n.SodaMessageSource
|
||||
@@ -487,7 +488,7 @@ class ExplorerQueryRepository(
|
||||
GetCheersResponseItem(
|
||||
cheersId = it.id!!,
|
||||
memberId = it.member!!.id!!,
|
||||
nickname = it.member!!.nickname,
|
||||
nickname = it.member!!.nickname.removeDeletedNicknamePrefix(),
|
||||
profileUrl = if (it.member!!.profileImage != null) {
|
||||
"$cloudFrontHost/${it.member!!.profileImage}"
|
||||
} else {
|
||||
@@ -505,7 +506,7 @@ class ExplorerQueryRepository(
|
||||
GetCheersResponseItem(
|
||||
cheersId = cheers.id!!,
|
||||
memberId = cheers.member!!.id!!,
|
||||
nickname = cheers.member!!.nickname,
|
||||
nickname = cheers.member!!.nickname.removeDeletedNicknamePrefix(),
|
||||
profileUrl = if (cheers.member!!.profileImage != null) {
|
||||
"$cloudFrontHost/${cheers.member!!.profileImage}"
|
||||
} else {
|
||||
|
||||
@@ -3,6 +3,7 @@ package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment
|
||||
import com.querydsl.core.types.dsl.Expressions
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment.QCreatorCommunityComment.creatorCommunityComment
|
||||
import kr.co.vividnext.sodalive.extensions.removeDeletedNicknamePrefix
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
import java.time.LocalDateTime
|
||||
@@ -93,8 +94,10 @@ class CreatorCommunityCommentQueryRepositoryImpl(
|
||||
.orderBy(creatorCommunityComment.createdAt.desc())
|
||||
.fetch()
|
||||
.map {
|
||||
it.replyCount = commentReplyCountByCommentId(it.id)
|
||||
it
|
||||
it.copy(
|
||||
nickname = it.nickname.removeDeletedNicknamePrefix(),
|
||||
replyCount = commentReplyCountByCommentId(it.id)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,5 +177,8 @@ class CreatorCommunityCommentQueryRepositoryImpl(
|
||||
.limit(limit)
|
||||
.orderBy(creatorCommunityComment.createdAt.desc())
|
||||
.fetch()
|
||||
.map {
|
||||
it.copy(nickname = it.nickname.removeDeletedNicknamePrefix())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
private const val DELETED_NICKNAME_PREFIX = "deleted_"
|
||||
|
||||
fun String.convertLocalDateTime(format: String): LocalDateTime {
|
||||
val dateTimeFormatter = DateTimeFormatter.ofPattern(format)
|
||||
return LocalDateTime.parse(this, dateTimeFormatter)
|
||||
@@ -24,3 +26,11 @@ fun String.convertLocalDateTime(
|
||||
.withZoneSameInstant(ZoneId.of("UTC"))
|
||||
.toLocalDateTime()
|
||||
}
|
||||
|
||||
fun String.removeDeletedNicknamePrefix(): String {
|
||||
return if (startsWith(DELETED_NICKNAME_PREFIX)) {
|
||||
removePrefix(DELETED_NICKNAME_PREFIX)
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package kr.co.vividnext.sodalive.extensions
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class StringExtensionsTest {
|
||||
@Test
|
||||
fun shouldRemoveDeletedPrefixWhenNicknameStartsWithDeletedPrefix() {
|
||||
val nickname = "deleted_testUser"
|
||||
|
||||
val sanitizedNickname = nickname.removeDeletedNicknamePrefix()
|
||||
|
||||
assertEquals("testUser", sanitizedNickname)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldKeepNicknameWhenDeletedPrefixDoesNotExist() {
|
||||
val nickname = "testUser"
|
||||
|
||||
val sanitizedNickname = nickname.removeDeletedNicknamePrefix()
|
||||
|
||||
assertEquals("testUser", sanitizedNickname)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldReturnEmptyStringWhenNicknameContainsOnlyDeletedPrefix() {
|
||||
val nickname = "deleted_"
|
||||
|
||||
val sanitizedNickname = nickname.removeDeletedNicknamePrefix()
|
||||
|
||||
assertEquals("", sanitizedNickname)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user