From 36a60c76ebb56a0af7f95937ce537647f175bf1e Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 26 Jun 2026 02:49:30 +0900 Subject: [PATCH] =?UTF-8?q?fix(member):=20=EC=96=B8=ED=8C=94=EB=A1=9C?= =?UTF-8?q?=EC=9A=B0=20=EC=8B=9C=20=EC=B5=9C=EA=B7=BC=20=EC=86=8C=EC=8B=9D?= =?UTF-8?q?=EC=9D=84=20=EB=B9=84=ED=99=9C=EC=84=B1=ED=99=94=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/member/MemberService.kt | 3 ++ .../member/MemberServiceCacheEvictionTest.kt | 1 + .../MemberServiceContentPreferenceTest.kt | 1 + .../sodalive/member/MemberServiceTest.kt | 52 +++++++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt index a6e790ff..559b9445 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt @@ -53,6 +53,7 @@ import kr.co.vividnext.sodalive.member.token.MemberTokenRepository import kr.co.vividnext.sodalive.point.MemberPointRepository import kr.co.vividnext.sodalive.utils.generateFileName import kr.co.vividnext.sodalive.utils.generatePassword +import kr.co.vividnext.sodalive.v2.home.following.port.out.HomeFollowingNewsInboxPort import org.springframework.beans.factory.annotation.Value import org.springframework.cache.CacheManager import org.springframework.data.repository.findByIdOrNull @@ -109,6 +110,7 @@ class MemberService( private val objectMapper: ObjectMapper, private val cacheManager: CacheManager, + private val homeFollowingNewsInboxPort: HomeFollowingNewsInboxPort, @Value("\${cloud.aws.s3.bucket}") private val s3Bucket: String, @@ -525,6 +527,7 @@ class MemberService( if (creatorFollowing != null) { creatorFollowing.isActive = false + homeFollowingNewsInboxPort.deactivateByMemberIdAndCreatorId(memberId = memberId, creatorId = creatorId) } } diff --git a/src/test/kotlin/kr/co/vividnext/sodalive/member/MemberServiceCacheEvictionTest.kt b/src/test/kotlin/kr/co/vividnext/sodalive/member/MemberServiceCacheEvictionTest.kt index ff2cb59b..556af54e 100644 --- a/src/test/kotlin/kr/co/vividnext/sodalive/member/MemberServiceCacheEvictionTest.kt +++ b/src/test/kotlin/kr/co/vividnext/sodalive/member/MemberServiceCacheEvictionTest.kt @@ -66,6 +66,7 @@ class MemberServiceCacheEvictionTest { memberContentPreferenceService = mock(), objectMapper = ObjectMapper(), cacheManager = cacheManager, + homeFollowingNewsInboxPort = mock(), s3Bucket = "test-bucket", cloudFrontHost = "https://cdn.test" ) diff --git a/src/test/kotlin/kr/co/vividnext/sodalive/member/MemberServiceContentPreferenceTest.kt b/src/test/kotlin/kr/co/vividnext/sodalive/member/MemberServiceContentPreferenceTest.kt index f4fb2ed5..fe7d6b2d 100644 --- a/src/test/kotlin/kr/co/vividnext/sodalive/member/MemberServiceContentPreferenceTest.kt +++ b/src/test/kotlin/kr/co/vividnext/sodalive/member/MemberServiceContentPreferenceTest.kt @@ -75,6 +75,7 @@ class MemberServiceContentPreferenceTest { memberContentPreferenceService = memberContentPreferenceService, objectMapper = ObjectMapper(), cacheManager = mock(), + homeFollowingNewsInboxPort = mock(), s3Bucket = "test-bucket", cloudFrontHost = "https://cdn.test" ) diff --git a/src/test/kotlin/kr/co/vividnext/sodalive/member/MemberServiceTest.kt b/src/test/kotlin/kr/co/vividnext/sodalive/member/MemberServiceTest.kt index e121cc68..c8625b6e 100644 --- a/src/test/kotlin/kr/co/vividnext/sodalive/member/MemberServiceTest.kt +++ b/src/test/kotlin/kr/co/vividnext/sodalive/member/MemberServiceTest.kt @@ -3,6 +3,9 @@ package kr.co.vividnext.sodalive.member import kr.co.vividnext.sodalive.common.SodaException import kr.co.vividnext.sodalive.member.login.LoginRequest import kr.co.vividnext.sodalive.support.EmbeddedRedisInitializer +import kr.co.vividnext.sodalive.v2.home.following.adapter.out.persistence.HomeFollowingNewsInbox +import kr.co.vividnext.sodalive.v2.home.following.adapter.out.persistence.HomeFollowingNewsInboxJpaRepository +import kr.co.vividnext.sodalive.v2.home.following.domain.FollowingNewsType import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertThrows import org.junit.jupiter.api.DisplayName @@ -11,6 +14,7 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.context.ContextConfiguration import org.springframework.transaction.annotation.Transactional +import java.time.LocalDateTime import javax.persistence.EntityManager @SpringBootTest @@ -19,6 +23,7 @@ import javax.persistence.EntityManager class MemberServiceTest @Autowired constructor( private val service: MemberService, private val memberRepository: MemberRepository, + private val homeFollowingNewsInboxJpaRepository: HomeFollowingNewsInboxJpaRepository, private val entityManager: EntityManager ) { @Test @@ -42,4 +47,51 @@ class MemberServiceTest @Autowired constructor( assertEquals("common.error.bad_credentials", exception.messageKey) } + + @Test + @DisplayName("언팔로우 성공 시 해당 회원과 크리에이터의 활성 최근 소식을 비활성화하고 재팔로우해도 복구하지 않는다") + fun shouldDeactivateFollowingNewsInboxOnCreatorUnFollowAndKeepInactiveAfterRefollow() { + val member = memberRepository.save(Member(email = "follower@test.com", password = "password", nickname = "follower")) + val creator = memberRepository.save( + Member( + email = "creator@test.com", + password = "password", + nickname = "creator", + role = MemberRole.CREATOR + ) + ) + service.creatorFollow(creatorId = creator.id!!, isNotify = true, isActive = true, memberId = member.id!!) + val inbox = homeFollowingNewsInboxJpaRepository.save( + HomeFollowingNewsInbox( + memberId = member.id!!, + creatorId = creator.id!!, + newsType = FollowingNewsType.COMMUNITY_POST, + sourceKey = "COMMUNITY_POST:1", + targetId = 1L, + occurredAtUtc = LocalDateTime.of(2026, 6, 25, 1, 0), + visibleFromAtUtc = LocalDateTime.of(2026, 6, 25, 1, 0), + creatorNickname = "creator", + creatorProfileImagePath = null, + title = "title", + body = "body", + thumbnailImagePath = null, + rank = null, + isAdult = false + ) + ) + entityManager.flush() + entityManager.clear() + + service.creatorUnFollow(creatorId = creator.id!!, memberId = member.id!!) + entityManager.flush() + entityManager.clear() + + assertEquals(false, homeFollowingNewsInboxJpaRepository.findById(inbox.id!!).get().isActive) + + service.creatorFollow(creatorId = creator.id!!, isNotify = true, isActive = true, memberId = member.id!!) + entityManager.flush() + entityManager.clear() + + assertEquals(false, homeFollowingNewsInboxJpaRepository.findById(inbox.id!!).get().isActive) + } }