fix(chat): 배너 목록 응답 생성을 서비스로 옮긴다

This commit is contained in:
2026-06-29 11:24:21 +09:00
parent 9a241f7137
commit 036cd40539
2 changed files with 91 additions and 2 deletions

View File

@@ -1,5 +1,7 @@
package kr.co.vividnext.sodalive.chat.character.service package kr.co.vividnext.sodalive.chat.character.service
import kr.co.vividnext.sodalive.admin.chat.dto.ChatCharacterBannerListPageResponse
import kr.co.vividnext.sodalive.admin.chat.dto.ChatCharacterBannerResponse
import kr.co.vividnext.sodalive.chat.character.ChatCharacterBanner import kr.co.vividnext.sodalive.chat.character.ChatCharacterBanner
import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterBannerRepository import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterBannerRepository
import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterRepository import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterRepository
@@ -11,6 +13,7 @@ import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional import org.springframework.transaction.annotation.Transactional
@Service @Service
@Transactional(readOnly = true)
class ChatCharacterBannerService( class ChatCharacterBannerService(
private val bannerRepository: ChatCharacterBannerRepository, private val bannerRepository: ChatCharacterBannerRepository,
private val characterRepository: ChatCharacterRepository private val characterRepository: ChatCharacterRepository
@@ -18,8 +21,18 @@ class ChatCharacterBannerService(
/** /**
* 활성화된 모든 배너 조회 (정렬 순서대로) * 활성화된 모든 배너 조회 (정렬 순서대로)
*/ */
fun getActiveBanners(pageable: Pageable): Page<ChatCharacterBanner> { fun getActiveBanners(pageable: Pageable, imageHost: String): ChatCharacterBannerListPageResponse {
return bannerRepository.findByIsActiveTrueOrderBySortOrderAsc(pageable) val banners = bannerRepository.findByIsActiveTrueOrderBySortOrderAsc(pageable)
return ChatCharacterBannerListPageResponse(
totalCount = banners.totalElements,
content = banners.content.map {
ChatCharacterBannerResponse.from(
banner = it,
imageHost = imageHost,
appendLanguageToCharacterName = true
)
}
)
} }
fun getDisplayBanners(pageable: Pageable, lang: Lang): Page<ChatCharacterBanner> { fun getDisplayBanners(pageable: Pageable, lang: Lang): Page<ChatCharacterBanner> {

View File

@@ -0,0 +1,76 @@
package kr.co.vividnext.sodalive.chat.character.service
import kr.co.vividnext.sodalive.chat.character.ChatCharacter
import kr.co.vividnext.sodalive.chat.character.ChatCharacterBanner
import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterBannerRepository
import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterRepository
import kr.co.vividnext.sodalive.i18n.Lang
import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.member.MemberRepository
import kr.co.vividnext.sodalive.member.MemberRole
import kr.co.vividnext.sodalive.support.EmbeddedRedisInitializer
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.data.domain.PageRequest
import org.springframework.test.annotation.DirtiesContext
import org.springframework.test.context.ContextConfiguration
import javax.persistence.EntityManager
@SpringBootTest(
properties = [
"cloud.aws.cloud-front.host=https://cdn.test",
"spring.datasource.url=jdbc:h2:mem:chat-banner-service-integration;" +
"MODE=MySQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=VALUE;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"
]
)
@ContextConfiguration(initializers = [EmbeddedRedisInitializer::class])
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
class ChatCharacterBannerServiceIntegrationTest @Autowired constructor(
private val service: ChatCharacterBannerService,
private val characterRepository: ChatCharacterRepository,
private val bannerRepository: ChatCharacterBannerRepository,
private val memberRepository: MemberRepository,
private val entityManager: EntityManager
) {
@Test
@DisplayName("OSIV off 환경에서 관리자 배너 목록 응답 생성 시 lazy 초기화 예외가 발생하지 않는다")
fun shouldCreateAdminBannerListResponseWhenOpenInViewIsDisabled() {
val creator = memberRepository.saveAndFlush(
Member(
email = "character-admin-banner-service@test.com",
password = "password",
nickname = "character-admin-banner-creator",
role = MemberRole.CREATOR
)
)
val character = characterRepository.saveAndFlush(
ChatCharacter(
characterUUID = "character-admin-banner-service",
name = "character-admin-banner",
description = "description",
systemPrompt = "system-prompt"
).apply {
creatorMember = creator
}
)
bannerRepository.saveAndFlush(
ChatCharacterBanner(
imagePath = "banner/jp.png",
chatCharacter = character,
sortOrder = 1,
lang = Lang.JA
)
)
entityManager.clear()
val response = service.getActiveBanners(PageRequest.of(0, 20), "https://cdn.test")
assertEquals(1, response.totalCount)
assertEquals(character.id, response.content.first().characterId)
assertEquals("character-admin-banner (일본어)", response.content.first().characterName)
assertEquals("https://cdn.test/banner/jp.png", response.content.first().imagePath)
}
}