Skip to content

test: PublicCourseService 단위 테스트 추가 + 버그 4건 수정 - #215

Merged
unam98 merged 1 commit into
devfrom
tests/public-course-service-unit-tests
Aug 5, 2026
Merged

test: PublicCourseService 단위 테스트 추가 + 버그 4건 수정#215
unam98 merged 1 commit into
devfrom
tests/public-course-service-unit-tests

Conversation

@unam98

@unam98 unam98 commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

작업 배경

  • 테스트 커버리지 확장 4단계(JwtService/UserIdResolver → CourseService → RecordService → PublicCourseService). 앱에서 가장 크고 핵심적인 도메인 서비스에 단위 테스트를 붙이고, 테스트 작성 중 발견한 실제 버그를 함께 수정.

변경 사항

영역 내용
PublicCourse id 기준 equals/hashCode 추가 (RunnectUser와 동일한 참조비교 문제 해결)
PublicCourseService.getPublicCourseDetail 삭제된 코스 체크 조건 반전 + 누락된 throw 추가
PublicCourseService.updatePublicCourse userId 소유권 검증 추가 (IDOR 방지), 관리자 예외 허용
PublicCourseService.recommendPublicCourse 잘못된 sort 값일 때 NPE 대신 BadRequestException
ErrorStatus PERMISSION_DENIED_PUBLIC_COURSE_UPDATE_EXCEPTION 추가
PublicCourseServiceTest 9개 메서드 전체에 대해 정상/예외/경계값 테스트 38개 신규

영향 범위

  • PublicCourse.equals/hashCode 변경은 이 엔티티를 비교하는 모든 곳(스크랩 매칭 로직 5곳)에 영향. 값 기반 비교로 바뀌어 기존에 놓치던 매칭이 이제 정확히 잡힘 — 동작이 "고쳐지는" 방향의 변경이라 별도 마이그레이션 불필요.
  • updatePublicCourse는 이제 소유자가 아니면 403을 반환함 (기존엔 아무나 수정 가능했음) — 클라이언트가 이 케이스를 이미 정상 동작으로 오인해 의존하고 있었다면 영향 있을 수 있음.
  • recommendPublicCourse는 잘못된 sort 값일 때 500(NPE) 대신 400을 반환함 — 클라이언트 에러 핸들링에 더 명확한 신호.
  • 런타임 영향: 캐시(@Cacheable)가 걸린 두 메서드(getMarathonPublicCourse, recommendPublicCourse)는 로직만 바뀌고 캐시 키/설정은 그대로.

검증 매트릭스

영향 범위 테스트 코드
전체 페이지 수 계산 (나누어떨어짐/안떨어짐/0건) 나누어_떨어짐
나누어_안_떨어짐
코스가_없음
마라톤 코스 조회 + 스크랩 매칭(PublicCourse equals 수정 검증) 정상_조회
마라톤_코스_일부_없음
존재하지_않는_유저
키워드 검색 + 스크랩 매칭 정상_검색
검색_결과_없음
추천 코스 정렬(scrap/date) + 잘못된 정렬값 처리(신규 수정) 스크랩순_정렬
최신순_정렬
잘못된_정렬값
유저별 공개 코스 목록 조회 정상_조회
공개한_코스_없음
공개 코스 상세 - 삭제된 코스 체크(신규 수정 검증) 삭제된_코스
공개 코스 상세 - 본인/타인/탈퇴유저 판정 + 스크랩 매칭 정상_조회_건물명_있음
정상_조회_건물명_없음
타인_코스
업로더가_없는_코스
스크랩_매칭
공개 코스 생성 - 소유권/중복 검증 정상_생성
소유자가_아님
이미_공개된_코스
공개 코스 삭제 - 소유권/관리자 예외 정상_삭제
소유자가_아닌_코스_포함
관리자는_소유자가_아니어도_삭제_가능
공개 코스 수정 - IDOR 방지(신규 수정 검증) + 관리자 예외 소유자가_아니면_수정_불가
관리자는_소유자가_아니어도_수정_가능
정상_수정

Test Plan

  • 로컬에서 신규 테스트 38개 전부 통과
  • 기존 JwtService/UserIdResolver/CourseService/RecordService/RunnectUser 테스트와 함께 실행해도 간섭 없음 확인
  • 로컬 DB/Redis 띄우고 ./gradlew build 전체(기존 ServerApplicationTests 포함) 통과 확인

🤖 Generated with Claude Code

getPublicCourseTotalPageCount/getMarathonPublicCourse/searchPublicCourse/
recommendPublicCourse/getPublicCourseByUser/getPublicCourseDetail/
createPublicCourse/deletePublicCourses/updatePublicCourse 전체 메서드에
대해 정상 케이스 + 예외 케이스 + 경계값 검증 (38개).

테스트 작성 중 발견해서 함께 수정한 버그 4건:
1. PublicCourse에 equals/hashCode 부재 — RunnectUser와 동일한 참조비교 문제.
   scrap 목록과 publicCourse 목록을 서로 다른 쿼리로 가져와 비교하는 곳이
   5곳(getMarathonPublicCourse, searchPublicCourse, recommendPublicCourse,
   getPublicCourseByUser, getPublicCourseDetail)이라 isScrap이 잘못 표시될
   수 있었음. id 기준 equals/hashCode 추가로 일괄 해결.
2. getPublicCourseDetail: 삭제된 코스 체크 조건이 반대(`== null`)였고,
   심지어 예외를 생성만 하고 throw를 안 해서 완전히 죽은 코드였음. 조건
   반전 + throw 추가.
3. updatePublicCourse: userId를 받으면서 소유권 검증을 안 해 다른 사람의
   공개 코스 제목/설명도 수정 가능했음 (IDOR). deletePublicCourses와
   동일한 관리자 예외 패턴으로 소유권 검증 추가.
   ErrorStatus.PERMISSION_DENIED_PUBLIC_COURSE_UPDATE_EXCEPTION 추가.
4. recommendPublicCourse: sort 파라미터가 "scrap"/"date" 둘 다 아니면
   Page 변수가 null로 남아 NPE. 이미 정의돼 있던
   INVALID_SORT_PARAMETER_EXCEPTION을 실제로 사용하도록 수정.
@unam98 unam98 self-assigned this Aug 5, 2026
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@unam98, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 20 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 90547ec9-318f-4cee-8157-9f4c92b1d1a4

📥 Commits

Reviewing files that changed from the base of the PR and between 69fd6e4 and d80d660.

📒 Files selected for processing (4)
  • src/main/java/org/runnect/server/common/constant/ErrorStatus.java
  • src/main/java/org/runnect/server/publicCourse/entity/PublicCourse.java
  • src/main/java/org/runnect/server/publicCourse/service/PublicCourseService.java
  • src/test/java/org/runnect/server/publicCourse/service/PublicCourseServiceTest.java

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.

@unam98
unam98 merged commit 92e9d55 into dev Aug 5, 2026
2 checks passed
@unam98
unam98 deleted the tests/public-course-service-unit-tests branch August 5, 2026 10:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants