diff --git a/roome/src/main/java/com/roome/domain/rank/service/RankingScheduler.java b/roome/src/main/java/com/roome/domain/rank/service/RankingScheduler.java index 7e6e40f4..21186168 100644 --- a/roome/src/main/java/com/roome/domain/rank/service/RankingScheduler.java +++ b/roome/src/main/java/com/roome/domain/rank/service/RankingScheduler.java @@ -1,11 +1,7 @@ package com.roome.domain.rank.service; -import com.roome.domain.point.entity.Point; -import com.roome.domain.point.entity.PointHistory; import com.roome.domain.point.entity.PointReason; -import com.roome.domain.point.exception.PointNotFoundException; -import com.roome.domain.point.repository.PointHistoryRepository; -import com.roome.domain.point.repository.PointRepository; +import com.roome.domain.point.service.PointService; import com.roome.domain.rank.entity.UserActivity; import com.roome.domain.rank.repository.UserActivityRepository; import com.roome.domain.user.entity.User; @@ -34,8 +30,7 @@ public class RankingScheduler { private final RedisTemplate rankingRedisTemplate; private final UserActivityRepository userActivityRepository; private final UserRepository userRepository; - private final PointRepository pointRepository; - private final PointHistoryRepository pointHistoryRepository; + private final PointService pointService; private static final String RANKING_KEY = "user:ranking"; @@ -124,22 +119,12 @@ public void awardWeeklyPoints() { default: continue; } - int points = reason.getAmount(); - // Point 엔티티 조회 - Point pointEntity = pointRepository.findByUserId(user.getId()) - .orElseThrow(PointNotFoundException::new); - - // 포인트 적립 - pointEntity.addPoints(points); - pointRepository.save(pointEntity); - - // 포인트 히스토리 기록 - PointHistory history = new PointHistory(user, points, reason); - pointHistoryRepository.save(history); + // 포인트 적립은 PointService 단일 경로로 위임 + pointService.earnPoints(user, reason); log.info("포인트 지급: 유저={}, 순위={}, 점수={}, 포인트={}", userId, rank, - score != null ? score.intValue() : 0, points); + score != null ? score.intValue() : 0, reason.getAmount()); } catch (NumberFormatException e) { log.error("랭킹 데이터 처리 중 형변환 오류: {}", e.getMessage()); } diff --git a/roome/src/test/java/com/roome/domain/rank/service/RankingSchedulerTest.java b/roome/src/test/java/com/roome/domain/rank/service/RankingSchedulerTest.java index e814c211..14b6cb9b 100644 --- a/roome/src/test/java/com/roome/domain/rank/service/RankingSchedulerTest.java +++ b/roome/src/test/java/com/roome/domain/rank/service/RankingSchedulerTest.java @@ -5,10 +5,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.roome.domain.point.entity.Point; -import com.roome.domain.point.entity.PointHistory; -import com.roome.domain.point.repository.PointHistoryRepository; -import com.roome.domain.point.repository.PointRepository; +import com.roome.domain.point.entity.PointReason; +import com.roome.domain.point.service.PointService; import com.roome.domain.rank.repository.UserActivityRepository; import com.roome.domain.user.entity.User; import com.roome.domain.user.repository.UserRepository; @@ -43,10 +41,7 @@ public class RankingSchedulerTest { private UserRepository userRepository; @Mock - private PointRepository pointRepository; - - @Mock - private PointHistoryRepository pointHistoryRepository; + private PointService pointService; @InjectMocks private RankingScheduler rankingScheduler; @@ -82,39 +77,22 @@ void awardWeeklyPointsTest() { when(zSetOperations.reverseRangeWithScores("user:ranking", 0, 2)).thenReturn(topRankers); - // 유저 정보 모킹 - ID 명시적 설정 + // 유저 정보 모킹 User user1 = Mockito.mock(User.class); - when(user1.getId()).thenReturn(1L); - User user2 = Mockito.mock(User.class); - when(user2.getId()).thenReturn(2L); - User user3 = Mockito.mock(User.class); - when(user3.getId()).thenReturn(3L); when(userRepository.findById(1L)).thenReturn(Optional.of(user1)); when(userRepository.findById(2L)).thenReturn(Optional.of(user2)); when(userRepository.findById(3L)).thenReturn(Optional.of(user3)); - // 포인트 정보 모킹 - Point point1 = Mockito.mock(Point.class); - Point point2 = Mockito.mock(Point.class); - Point point3 = Mockito.mock(Point.class); - - when(pointRepository.findByUserId(1L)).thenReturn(Optional.of(point1)); - when(pointRepository.findByUserId(2L)).thenReturn(Optional.of(point2)); - when(pointRepository.findByUserId(3L)).thenReturn(Optional.of(point3)); - // When rankingScheduler.awardWeeklyPoints(); - // Then - verify(point1).addPoints(100); - verify(point2).addPoints(70); - verify(point3).addPoints(50); - - verify(pointRepository, times(3)).save(any(Point.class)); - verify(pointHistoryRepository, times(3)).save(any(PointHistory.class)); + // Then: 순위별 사유로 PointService 단일 경로를 통해 지급된다 (원자 적립 + 이력 + 캐시 무효화) + verify(pointService).earnPoints(user1, PointReason.RANK_1); + verify(pointService).earnPoints(user2, PointReason.RANK_2); + verify(pointService).earnPoints(user3, PointReason.RANK_3); verify(userActivityRepository).deleteAllByCreatedAtBefore(any(LocalDateTime.class));