Merge pull request 'fix(admin-chat-character): JP 리전 캐릭터 등록 성별 값을 일본어로 변환한다' (#401) from test into main
Reviewed-on: #401
This commit is contained in:
23
docs/20260316_캐릭터등록JP성별일본어변환.md
Normal file
23
docs/20260316_캐릭터등록JP성별일본어변환.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# 캐릭터 등록 JP 성별 일본어 변환
|
||||
|
||||
- [x] `AdminChatCharacterController.registerCharacter`의 외부 API 호출 경로 확인
|
||||
- QA: `callExternalApi`에서 `region`/`gender` 바디 구성 위치 확인
|
||||
- [x] `region == JP`일 때 `gender` 값을 일본어로 변환하는 로직 추가
|
||||
- QA: `여성 -> 女性`, `남성 -> 男性`, `기타 -> その他` 매핑 확인
|
||||
- [x] 등록 API 외부 호출 시에만 변환이 적용되도록 구현
|
||||
- QA: DB 저장용 `request.gender`는 기존 값 유지 여부 확인
|
||||
- [x] 정적 진단 및 테스트 수행
|
||||
- QA: Kotlin LSP 미구성으로 `lsp_diagnostics` 불가 확인, `./gradlew test --tests "kr.co.vividnext.sodalive.admin.chat.character.AdminChatCharacterControllerTest"` 및 `./gradlew build -x test` 성공
|
||||
|
||||
## 검증 기록
|
||||
|
||||
### 1차 구현
|
||||
- 무엇을: `registerCharacter` 외부 API 호출 시 `region == JP` 조건에서만 `gender`를 일본어(`女性`/`男性`/`その他`)로 변환하도록 구현하고, 매핑 단위 테스트를 추가했다.
|
||||
- 왜: JP 리전 요청에서 외부 API가 일본어 성별 값을 요구하므로 등록 API 요청 바디의 `gender` 값만 조건부 변환이 필요했다.
|
||||
- 어떻게:
|
||||
- 코드 확인: `src/main/kotlin/kr/co/vividnext/sodalive/admin/chat/character/AdminChatCharacterController.kt`에서 `callExternalApi` 바디 구성 지점 확인 후 `mapGenderForExternalApi` 헬퍼 추가
|
||||
- 매핑 검증: `src/test/kotlin/kr/co/vividnext/sodalive/admin/chat/character/AdminChatCharacterControllerTest.kt`에서 JP 매핑(여성/남성/기타) 및 KR 유지 케이스 검증
|
||||
- 정적 진단: `lsp_diagnostics` 실행 시 Kotlin LSP 미구성으로 불가(환경 제약)
|
||||
- 실행 검증 1: `./gradlew test --tests "kr.co.vividnext.sodalive.admin.chat.character.AdminChatCharacterControllerTest"` → 성공
|
||||
- 수동 확인: `build/test-results/test/TEST-kr.co.vividnext.sodalive.admin.chat.character.AdminChatCharacterControllerTest.xml`에서 `tests="4" failures="0" errors="0"` 확인
|
||||
- 실행 검증 2: `./gradlew build -x test` → 성공
|
||||
@@ -206,7 +206,7 @@ class AdminChatCharacterController(
|
||||
body["description"] = request.description
|
||||
body["region"] = request.region
|
||||
request.age?.let { body["age"] = it }
|
||||
request.gender?.let { body["gender"] = it }
|
||||
request.gender?.let { body["gender"] = mapGenderForExternalApi(request.region, it) }
|
||||
request.mbti?.let { body["mbti"] = it }
|
||||
request.speechPattern?.let { body["speechPattern"] = it }
|
||||
request.speechStyle?.let { body["speechStyle"] = it }
|
||||
@@ -273,6 +273,19 @@ class AdminChatCharacterController(
|
||||
}
|
||||
}
|
||||
|
||||
private fun mapGenderForExternalApi(region: String, gender: String): String {
|
||||
if (!region.equals("JP", ignoreCase = true)) {
|
||||
return gender
|
||||
}
|
||||
|
||||
return when (gender) {
|
||||
"여성" -> "女性"
|
||||
"남성" -> "男性"
|
||||
"기타" -> "その他"
|
||||
else -> gender
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 캐릭터 수정 API
|
||||
* 1. JSON 문자열을 ChatCharacterUpdateRequest 객체로 변환
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package kr.co.vividnext.sodalive.admin.chat.character
|
||||
|
||||
import kr.co.vividnext.sodalive.admin.chat.character.service.AdminChatCharacterService
|
||||
import kr.co.vividnext.sodalive.admin.chat.original.service.AdminOriginalWorkService
|
||||
import kr.co.vividnext.sodalive.aws.s3.S3Uploader
|
||||
import kr.co.vividnext.sodalive.chat.character.service.ChatCharacterService
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.Mockito
|
||||
import org.springframework.context.ApplicationEventPublisher
|
||||
|
||||
class AdminChatCharacterControllerTest {
|
||||
private val controller = AdminChatCharacterController(
|
||||
service = Mockito.mock(ChatCharacterService::class.java),
|
||||
adminService = Mockito.mock(AdminChatCharacterService::class.java),
|
||||
s3Uploader = Mockito.mock(S3Uploader::class.java),
|
||||
originalWorkService = Mockito.mock(AdminOriginalWorkService::class.java),
|
||||
applicationEventPublisher = Mockito.mock(ApplicationEventPublisher::class.java),
|
||||
apiKey = "test-api-key",
|
||||
apiUrl = "https://example.com",
|
||||
s3Bucket = "test-bucket",
|
||||
imageHost = "https://cdn.example.com"
|
||||
)
|
||||
|
||||
private fun mapGender(region: String, gender: String): String {
|
||||
val method = AdminChatCharacterController::class.java.getDeclaredMethod(
|
||||
"mapGenderForExternalApi",
|
||||
String::class.java,
|
||||
String::class.java
|
||||
)
|
||||
method.isAccessible = true
|
||||
|
||||
return method.invoke(controller, region, gender) as String
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldMapFemaleToJapaneseWhenRegionIsJp() {
|
||||
val mappedGender = mapGender(region = "JP", gender = "여성")
|
||||
|
||||
assertEquals("女性", mappedGender)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldMapMaleToJapaneseWhenRegionIsJp() {
|
||||
val mappedGender = mapGender(region = "JP", gender = "남성")
|
||||
|
||||
assertEquals("男性", mappedGender)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldMapOtherToJapaneseWhenRegionIsJp() {
|
||||
val mappedGender = mapGender(region = "JP", gender = "기타")
|
||||
|
||||
assertEquals("その他", mappedGender)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldKeepGenderWhenRegionIsNotJp() {
|
||||
val mappedGender = mapGender(region = "KR", gender = "여성")
|
||||
|
||||
assertEquals("여성", mappedGender)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user