From c80483815334b99ef4d9c09396bcf1a036cc76a9 Mon Sep 17 00:00:00 2001 From: jyx-07 Date: Mon, 3 Aug 2026 14:31:55 +0900 Subject: [PATCH] =?UTF-8?q?update=20::=20SSE=20=EC=95=84=EB=B0=94=ED=83=80?= =?UTF-8?q?=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20=EC=8B=9C=20?= =?UTF-8?q?=EC=A0=84=EC=B2=B4=20=EC=97=94=ED=8B=B0=ED=8B=B0=20=EB=8C=80?= =?UTF-8?q?=EC=8B=A0=20=ED=94=84=EB=A1=9C=EC=A0=9D=EC=85=98=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../avatar/repository/AvatarRepository.kt | 2 +- .../repository/AvatarSummaryProjection.kt | 19 ++++++++++++++ .../SubscribeAvatarChangesServiceImpl.kt | 4 +-- .../SubscribeAvatarChangesServiceImplTest.kt | 26 +++++++++++-------- 4 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 src/main/kotlin/team/darkmoderap/aikon/domain/avatar/repository/AvatarSummaryProjection.kt diff --git a/src/main/kotlin/team/darkmoderap/aikon/domain/avatar/repository/AvatarRepository.kt b/src/main/kotlin/team/darkmoderap/aikon/domain/avatar/repository/AvatarRepository.kt index 1794caf..8ba3ed7 100644 --- a/src/main/kotlin/team/darkmoderap/aikon/domain/avatar/repository/AvatarRepository.kt +++ b/src/main/kotlin/team/darkmoderap/aikon/domain/avatar/repository/AvatarRepository.kt @@ -5,7 +5,7 @@ import org.springframework.data.jpa.repository.Query import team.darkmoderap.aikon.domain.avatar.entity.AvatarEntity interface AvatarRepository : JpaRepository { - fun findAllByOrderByIdAsc(): List + fun findAllByOrderByIdAsc(): List fun findByPassUrl(passUrl: String): AvatarEntity? diff --git a/src/main/kotlin/team/darkmoderap/aikon/domain/avatar/repository/AvatarSummaryProjection.kt b/src/main/kotlin/team/darkmoderap/aikon/domain/avatar/repository/AvatarSummaryProjection.kt new file mode 100644 index 0000000..53edb4d --- /dev/null +++ b/src/main/kotlin/team/darkmoderap/aikon/domain/avatar/repository/AvatarSummaryProjection.kt @@ -0,0 +1,19 @@ +package team.darkmoderap.aikon.domain.avatar.repository + +import team.darkmoderap.aikon.domain.avatar.entity.enum.AgeRange +import team.darkmoderap.aikon.domain.avatar.entity.enum.Gender +import team.darkmoderap.aikon.domain.avatar.entity.enum.GenerationStatus +import team.darkmoderap.aikon.domain.avatar.entity.enum.Style +import java.time.Instant + +interface AvatarSummaryProjection { + val id: Long + val nickname: String + val style: Style + val gender: Gender + val ageRange: AgeRange + val generationStatus: GenerationStatus + val imageUrl: String? + val passUrl: String? + val createdAt: Instant +} diff --git a/src/main/kotlin/team/darkmoderap/aikon/domain/avatar/service/SubscribeAvatarChangesServiceImpl.kt b/src/main/kotlin/team/darkmoderap/aikon/domain/avatar/service/SubscribeAvatarChangesServiceImpl.kt index 66bf2de..27510f2 100644 --- a/src/main/kotlin/team/darkmoderap/aikon/domain/avatar/service/SubscribeAvatarChangesServiceImpl.kt +++ b/src/main/kotlin/team/darkmoderap/aikon/domain/avatar/service/SubscribeAvatarChangesServiceImpl.kt @@ -14,10 +14,10 @@ import org.springframework.transaction.event.TransactionalEventListener import org.springframework.transaction.support.TransactionTemplate import org.springframework.web.servlet.mvc.method.annotation.SseEmitter import team.darkmoderap.aikon.domain.avatar.dto.AvatarChangeResDto -import team.darkmoderap.aikon.domain.avatar.entity.AvatarEntity import team.darkmoderap.aikon.domain.avatar.event.AvatarListChangedEvent import team.darkmoderap.aikon.domain.avatar.event.AvatarSseSubscribedEvent import team.darkmoderap.aikon.domain.avatar.repository.AvatarRepository +import team.darkmoderap.aikon.domain.avatar.repository.AvatarSummaryProjection import team.darkmoderap.aikon.global.common.error.AikonException import team.darkmoderap.aikon.global.common.error.ErrorCode import java.util.concurrent.CopyOnWriteArrayList @@ -127,7 +127,7 @@ class SubscribeAvatarChangesServiceImpl( } } - private fun AvatarEntity.toChangeResDto(): AvatarChangeResDto = + private fun AvatarSummaryProjection.toChangeResDto(): AvatarChangeResDto = AvatarChangeResDto( id = id, nickname = nickname, diff --git a/src/test/kotlin/team/darkmoderap/aikon/domain/avatar/service/SubscribeAvatarChangesServiceImplTest.kt b/src/test/kotlin/team/darkmoderap/aikon/domain/avatar/service/SubscribeAvatarChangesServiceImplTest.kt index 6d5c800..f16de6a 100644 --- a/src/test/kotlin/team/darkmoderap/aikon/domain/avatar/service/SubscribeAvatarChangesServiceImplTest.kt +++ b/src/test/kotlin/team/darkmoderap/aikon/domain/avatar/service/SubscribeAvatarChangesServiceImplTest.kt @@ -16,7 +16,6 @@ import org.springframework.transaction.PlatformTransactionManager import org.springframework.transaction.TransactionDefinition import org.springframework.transaction.TransactionStatus import org.springframework.web.servlet.mvc.method.annotation.SseEmitter -import team.darkmoderap.aikon.domain.avatar.entity.AvatarEntity import team.darkmoderap.aikon.domain.avatar.entity.enum.AgeRange import team.darkmoderap.aikon.domain.avatar.entity.enum.Gender import team.darkmoderap.aikon.domain.avatar.entity.enum.GenerationStatus @@ -24,7 +23,9 @@ import team.darkmoderap.aikon.domain.avatar.entity.enum.Style import team.darkmoderap.aikon.domain.avatar.event.AvatarListChangedEvent import team.darkmoderap.aikon.domain.avatar.event.AvatarSseSubscribedEvent import team.darkmoderap.aikon.domain.avatar.repository.AvatarRepository +import team.darkmoderap.aikon.domain.avatar.repository.AvatarSummaryProjection import team.darkmoderap.aikon.global.common.error.AikonException +import java.time.Instant @ExtendWith(MockitoExtension::class) class SubscribeAvatarChangesServiceImplTest { @@ -94,7 +95,7 @@ class SubscribeAvatarChangesServiceImplTest { fun `finds latest avatar list when event is received`() { // Given given(transactionManager.getTransaction(any(TransactionDefinition::class.java))).willReturn(transactionStatus) - given(avatarRepository.findAllByOrderByIdAsc()).willReturn(listOf(avatar())) + given(avatarRepository.findAllByOrderByIdAsc()).willReturn(listOf(avatarSummaryProjection())) subscribeAvatarChangesService.execute() // When @@ -121,14 +122,17 @@ class SubscribeAvatarChangesServiceImplTest { } companion object { - private fun avatar(): AvatarEntity = - AvatarEntity( - nickname = "새아바타", - gender = Gender.FEMALE, - style = Style.GHIBLI, - ageRange = AgeRange.AGE_20_PLUS, - generationStatus = GenerationStatus.WAITING, - passUrl = "Aikon500", - ) + private fun avatarSummaryProjection(): AvatarSummaryProjection = + object : AvatarSummaryProjection { + override val id: Long = 1L + override val nickname: String = "새아바타" + override val style: Style = Style.GHIBLI + override val gender: Gender = Gender.FEMALE + override val ageRange: AgeRange = AgeRange.AGE_20_PLUS + override val generationStatus: GenerationStatus = GenerationStatus.WAITING + override val imageUrl: String? = null + override val passUrl: String? = "Aikon500" + override val createdAt: Instant = Instant.now() + } } }