Skip to content

Comments

[FIX] 종료된 챌린지는 인기 챌린지에서 조회되지 않도록 수정#300

Merged
yc3697 merged 1 commit intodevelopfrom
fix/299-popular-challenge-except-finished
Feb 7, 2026
Merged

[FIX] 종료된 챌린지는 인기 챌린지에서 조회되지 않도록 수정#300
yc3697 merged 1 commit intodevelopfrom
fix/299-popular-challenge-except-finished

Conversation

@yc3697
Copy link
Contributor

@yc3697 yc3697 commented Feb 7, 2026

#️⃣ 연관된 이슈

관련된 이슈 번호를 적어주세요.
Close #299

✨ 작업 내용 (Summary)

이번 PR에서 작업한 내용을 간략히 설명해주세요. (이미지 첨부 가능)

오늘의 인기 챌린지 조회 API에서 종료된 챌린지는 조회되지 않도록 수정하였습니다.


✅ 변경 사항 체크리스트

다음 항목들을 확인하고 체크해주세요.

  • 코드에 영향이 있는 모든 부분에 대한 테스트를 작성하고 실행했나요?
  • 문서를 작성하거나 수정했나요? (필요한 경우)
  • 중요한 변경 사항이 팀에 공유되었나요?

🧪 테스트 결과

코드 변경에 대해 테스트를 수행한 결과를 요약해주세요.

  • 테스트 환경: (예: 로컬, 개발 서버 등) 로컬
  • 테스트 방법: (예: Postman, 단위 테스트, 수동 기능 테스트 등) 단위 테스트
  • 결과 요약: (예: 모든 테스트 통과, 새로운 테스트 케이스 3개 추가 완료) 통과

📸 스크린샷

관련된 스크린샷 또는 GIF가 있다면 여기에 첨부해주세요.


💬 리뷰 요구사항

리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요.


📎 참고 자료

관련 문서, 레퍼런스 링크 등이 있다면 여기에 첨부해주세요.

Summary by CodeRabbit

릴리스 노트

  • Bug Fixes

    • 일일 최고 도전 목록에서 완료된 도전이 제외되도록 수정되었습니다.
  • Tests

    • 완료된 도전이 일일 최고 목록에서 올바르게 필터링되는지 검증하는 테스트가 추가되었습니다.

@yc3697 yc3697 self-assigned this Feb 7, 2026
@yc3697 yc3697 added 🐞 bug 버그 이슈 영찬 labels Feb 7, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 7, 2026

📝 Walkthrough

📋 개요

이 변경사항은 종료된 챌린지를 제외하는 리포지토리 메서드를 추가하고, 오늘의 인기 챌린지 조회에서 이를 활용하도록 업데이트합니다. 관련 단위 테스트도 함께 추가되었습니다.

🔄 변경사항

변경 영역 요약
리포지토리 계층
src/main/java/com/hrr/backend/domain/challenge/repository/ChallengeRepositoryCustom.java, src/main/java/com/hrr/backend/domain/challenge/repository/ChallengeRepositoryCustomImpl.java
메서드명을 findChallengesByIds에서 findNotFinishedChallengesByIds로 변경. 구현체에서 쿼리에 qChallenge.status.ne(ChallengeStatus.FINISHED) 필터 추가로 종료된 챌린지 제외.
서비스 계층
src/main/java/com/hrr/backend/domain/challenge/service/ChallengeServiceImpl.java
일일 인기 챌린지 조회 시 새로운 메서드명 findNotFinishedChallengesByIds 사용하도록 호출부 수정.
단위 테스트
src/test/java/com/hrr/backend/domain/challenge/service/ChallengeServiceImplTest.java
ChallengeServiceImplTest 새로운 테스트 클래스 추가. getDailyTopChallenges_FilterFinishedChallenges 테스트 메서드로 종료된 챌린지 필터링 검증. Mockito 활용하여 리포지토리, Redis, S3 등 의존성 모킹.

📊 코드 리뷰 예상 소요 시간

🎯 2 (Simple) | ⏱️ ~10분

분석 근거:

  • 일관된 메서드 이름 변경 패턴이 3개 파일에 걸쳐 반복 적용됨
  • 단일 필터 조건 추가로 로직 변경이 명확함
  • 테스트가 명확한 목적(종료된 챌린지 제외 검증)으로 잘 구성되어 있음
  • 구조적 리팩토링이 아닌 기능 추가/버그 수정 수준의 변경

✨ 축하 시

🏁 종료된 챌린지는 이제 안녕~
오늘의 인기 목록은 더 신선하게,
활동 중인 도전만 반짝 반짝 ✨
테스트도 든든하고!

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목이 변경 사항의 핵심을 명확하게 요약하고 있습니다. '[FIX] 종료된 챌린지는 인기 챌린지에서 조회되지 않도록 수정'은 연결된 이슈 #299의 목표와 일치합니다.
Linked Issues check ✅ Passed 모든 변경 사항이 이슈 #299의 요구사항을 충족합니다. 종료된 챌린지(FINISHED 상태)를 인기 챌린지 조회에서 제외하기 위해 쿼리 필터를 추가하고, 메서드명을 명확히 변경했으며, 단위 테스트를 통해 검증했습니다.
Out of Scope Changes check ✅ Passed 모든 변경이 이슈 #299의 요구사항 범위 내에 있습니다. 종료된 챌린지 제외 기능 구현, 메서드 이름 변경, 관련 테스트 추가 외에 불필요한 변경은 없습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/299-popular-challenge-except-finished

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/com/hrr/backend/domain/challenge/service/ChallengeServiceImpl.java (1)

368-395: ⚠️ Potential issue | 🟠 Major

enrichChallengeInfo에 기존 NPE 위험 및 중복 계산이 존재합니다

이 PR의 변경 사항은 아니지만, getDailyTopChallenges의 핵심 경로에 있으므로 짚어드립니다:

  1. Line 370: infoDto.getStartDate().toLocalDate()startDatenull이면 NPE 발생
  2. Line 373: challengeStartDate == null 체크가 이미 NPE가 발생한 이후에 위치함
  3. Lines 387-388: if-else 블록 바깥에서 dDayisUpcomingResult중복 계산하고 있으며, 이 값들은 사용되지 않음 (dead code)

startDate가 항상 non-null이라면 현재는 문제없지만, Projections.bean 매핑에서 DB 값이 null인 경우를 대비해 방어 코드를 권장합니다.

♻️ 개선 제안
 return rawInfos.stream()
     .map(infoDto -> {
-        LocalDate challengeStartDate = infoDto.getStartDate().toLocalDate();
         LocalDate today = LocalDate.now();
+        LocalDateTime startDateTime = infoDto.getStartDate();
 
-        if (challengeStartDate == null) {
+        if (startDateTime == null) {
             infoDto.setIsUpcoming(false);
             infoDto.setDDayUntilStart(0);
         } else {
+            LocalDate challengeStartDate = startDateTime.toLocalDate();
             long dDay = ChronoUnit.DAYS.between(today, challengeStartDate);
             boolean isUpcomingResult = (dDay >= 0) && (dDay <= UPCOMING_DAYS_CRITERIA);
             infoDto.setIsUpcoming(isUpcomingResult);
             infoDto.setDDayUntilStart((int)Math.max(0, dDay));
         }
 
-        long dDay = ChronoUnit.DAYS.between(today, challengeStartDate);
-        boolean isUpcomingResult = (dDay >= 0) && (dDay <= UPCOMING_DAYS_CRITERIA);
-
         infoDto.setThumbnailUrl(s3UrlUtil.toFullUrl(infoDto.getThumbnailUrl()));
         infoDto.setDaysOfWeek(daysMap.getOrDefault(infoDto.getChallengeId(), List.of()));
 
         return infoDto;
     }).toList();
🧹 Nitpick comments (3)
src/main/java/com/hrr/backend/domain/challenge/repository/ChallengeRepositoryCustomImpl.java (1)

83-99: ids 리스트 전달 시 SQL 오류 가능성 확인 필요

ids가 빈 리스트일 경우 qChallenge.id.in(ids)는 DB에 따라 IN () 구문으로 변환되어 SQL 오류를 유발할 수 있습니다. 호출부(getDailyTopChallenges)에서 currentListSize == 0이면 조기 반환하므로 현재는 안전하지만, 메서드가 다른 곳에서도 호출될 수 있으므로 방어 코드를 추가하는 것을 권장합니다.

🛡️ 방어 코드 제안
 `@Override`
 public List<ChallengeResponseDto.InfoDto> findNotFinishedChallengesByIds(List<Long> ids) {
+    if (ids == null || ids.isEmpty()) {
+        return List.of();
+    }
     return jpaQueryFactory
         .select(Projections.bean(ChallengeResponseDto.InfoDto.class,
src/test/java/com/hrr/backend/domain/challenge/service/ChallengeServiceImplTest.java (2)

39-80: 종료 챌린지 필터링에 대한 핵심 시나리오가 잘 검증되었습니다. 🎯

Redis → RDB → 필터링 → 결과 매핑의 전체 흐름을 깔끔하게 테스트하고 있습니다. 한 가지 보강 포인트를 제안드립니다:

  • verify(challengeRepository).findNotFinishedChallengesByIds(...) 호출 검증을 추가하면, 실제로 새 메서드가 호출되었는지 명시적으로 확인할 수 있습니다.
  • 추후 엣지 케이스(예: Redis에 있는 모든 챌린지가 종료된 경우 → 빈 리스트 반환) 테스트도 추가하면 더욱 견고해질 것입니다.

30-37: @InjectMocks 사용 시 누락된 의존성 주의

ChallengeServiceImpl은 다수의 의존성을 가지고 있으나, 현재 테스트에서는 5개만 @Mock으로 선언되어 있습니다. Mockito의 @InjectMocks는 매칭되지 않는 필드에 null을 주입합니다. 현재 테스트 메서드에서는 해당 경로를 타지 않으므로 문제없지만, 향후 테스트 메서드 추가 시 예상치 못한 NPE가 발생할 수 있습니다.

필요한 모든 의존성을 @Mock으로 선언하거나, 클래스 상단에 주석으로 의도를 명시해 두면 다음 개발자에게 도움이 됩니다.

@yc3697 yc3697 merged commit 2b8dedc into develop Feb 7, 2026
2 checks passed
@yc3697 yc3697 deleted the fix/299-popular-challenge-except-finished branch February 7, 2026 08:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

영찬 🐞 bug 버그 이슈

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FIX] 오늘의 인기 챌린지에서 종료된 챌린지는 조회되지 않도록 수정

1 participant