test: 핵심 피드백 루프 unit 테스트 보강#89
Conversation
- 기존 domain/service 테스트의 예외 분기와 경계값 검증 보강 - batch 피드백 루프 unit 테스트 신규 추가 - GitHub infra 및 전체 테스트 스위트 검증 추가
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthrough핵심 피드백 루프의 회귀 위험을 줄이기 위해 배치, 도메인, GitHub 인프라 계층에 걸쳐 광범위한 단위 테스트를 추가했습니다. 기존 테스트의 assertion과 예외 분기도 강화했으며, 값 객체 및 오케스트레이션 단위 테스트도 새로 도입했습니다. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f27868510d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (8)
src/test/java/com/gitranker/api/batch/listener/UserScoreCalculationSkipListenerTest.java (1)
33-34: 중복 리터럴은 상수화하면 테스트 유지보수가 더 쉬워집니다.
"DailyScoreRecalculationJob"와 사용자 식별자 문자열이 반복되어 변경 시 수정 지점이 늘어납니다. 테스트 클래스 내부 상수로 모아두는 정도는 가독성/유지보수에 도움이 됩니다.예시 diff
class UserScoreCalculationSkipListenerTest { + private static final String JOB_NAME = "DailyScoreRecalculationJob"; + private static final String USER_ALICE = "alice"; + private static final String UNKNOWN_USER = "UNKNOWN_USER"; @@ verify(batchFailureLogService).saveFailureLog( - "DailyScoreRecalculationJob", - "UNKNOWN_USER", + JOB_NAME, + UNKNOWN_USER, ErrorType.GITHUB_API_TIMEOUT, "[READ_PHASE] error.github.api-timeout: timeout" ); @@ - User user = TestFixtures.user("alice"); + User user = TestFixtures.user(USER_ALICE); @@ verify(batchFailureLogService).saveFailureLog( - "DailyScoreRecalculationJob", - "alice", + JOB_NAME, + USER_ALICE, ErrorType.DEFAULT_ERROR, "[PROCESS_PHASE] boom" ); @@ - User user = TestFixtures.user("alice"); + User user = TestFixtures.user(USER_ALICE); @@ verify(batchFailureLogService).saveFailureLog( - "DailyScoreRecalculationJob", - "alice", + JOB_NAME, + USER_ALICE, ErrorType.GITHUB_USER_NOT_FOUND, "[WRITE_PHASE] error.github.user-not-found" );Also applies to: 48-49, 63-64
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/test/java/com/gitranker/api/batch/listener/UserScoreCalculationSkipListenerTest.java` around lines 33 - 34, Replace repeated string literals in UserScoreCalculationSkipListenerTest by introducing private static final constants (e.g., JOB_NAME_DAILY_SCORE = "DailyScoreRecalculationJob" and UNKNOWN_USER_ID = "UNKNOWN_USER") at the top of the test class and use those constants wherever the literals appear (including the other occurrences currently used in assertions/setup), ensuring all occurrences in methods that reference the job name or user id (the repeated uses around the existing assertions and test setups) are updated to the new constants for easier maintenance.src/test/java/com/gitranker/api/domain/user/service/UserRegistrationServiceTest.java (1)
108-123: 테스트 의도는 맞지만null email보존 단언을 추가해 주세요.현재는
updateProfile미호출만 검증하고, 응답의권장 보강 예시
RegisterUserResponse response = userRegistrationService.register(attributes); assertThat(response.username()).isEqualTo("alice"); + assertThat(response.email()).isEqualTo("alice@example.com"); + assertThat(response.isNewUser()).isFalse(); verify(userPersistenceService, never()).updateProfile(any(User.class), any(String.class), any(String.class), any()); verify(gitHubActivityService, never()).fetchRawAllActivities(org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.any());🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/test/java/com/gitranker/api/domain/user/service/UserRegistrationServiceTest.java` around lines 108 - 123, Add an assertion that the returned RegisterUserResponse preserves the existing user's email: after calling userRegistrationService.register(attributes), assertThat(response.email()).isEqualTo(existingUser.getEmail()) (or assertThat(response.email()).isNull() if the fixture sets null), so the test verifies the email is unchanged in UserRegistrationServiceTest alongside the existing checks for updateProfile and gitHubActivityService calls.src/test/java/com/gitranker/api/domain/auth/service/AuthServiceTest.java (1)
131-140: 예외 검증에 부수효과 미발생 검증도 함께 넣는 것을 권장합니다.현재는 예외 타입만 확인해서, 추후 구현 변경으로 삭제/쿠키 정리가 잘못 호출되어도 테스트가 통과할 수 있습니다.
테스트 보강 예시
assertThatThrownBy(() -> authService.logout(savedUser(1L, "alice"), "missing", mock(HttpServletRequest.class), mock(HttpServletResponse.class))) .isInstanceOf(BusinessException.class) .extracting(exception -> ((BusinessException) exception).getErrorType()) .isEqualTo(ErrorType.INVALID_REFRESH_TOKEN); + verify(refreshTokenRepository, never()).deleteByToken("missing"); + verifyNoInteractions(authCookieManager);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/test/java/com/gitranker/api/domain/auth/service/AuthServiceTest.java` around lines 131 - 140, The test currently only asserts the thrown BusinessException for authService.logout; also verify no side effects occur by asserting that refresh token removal and cookie/header cleanup are not invoked: after calling logout(...) in the throwsWhenLogoutTokenDoesNotExist test, add Mockito verifications to ensure refreshTokenRepository.delete and/or refreshTokenRepository.deleteById are never called and HttpServletResponse.addCookie and HttpServletResponse.setHeader are never called (use the mocked HttpServletResponse passed into authService.logout) so the test fails if any deletion or cookie/header modifications happen unexpectedly.src/test/java/com/gitranker/api/infrastructure/github/token/TokenStateTest.java (1)
26-27: 시간값을 고정하면 테스트 안정성이 더 좋아집니다.
Instant.now()대신 고정Instant상수를 쓰면 실행 시점에 덜 민감해져서 테스트 재현성이 올라갑니다.예시 변경안
- Instant resetAt = Instant.now().plusSeconds(300); + Instant resetAt = Instant.parse("2026-04-16T18:00:00Z"); ... - state.update(0, Instant.now().minusSeconds(1)); + state.update(0, Instant.parse("2026-04-16T17:59:59Z"));Also applies to: 39-41
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/test/java/com/gitranker/api/infrastructure/github/token/TokenStateTest.java` around lines 26 - 27, In TokenStateTest, replace the time-dependent Instant.now() usage (the resetAt variable and the other Instant.now() usages around lines 39–41) with a fixed Instant constant (e.g. a private static final Instant FIXED_INSTANT) and derive offsets from that constant (use FIXED_INSTANT.plusSeconds(...) where offsets are needed) so tests become deterministic; update any assertions that referenced the previous dynamic times to use the fixed Instant-based values.src/test/java/com/gitranker/api/infrastructure/github/GitHubApiMetricsTest.java (1)
19-26:recordRateLimit인자 의미를 변수로 드러내 주세요.현재 리터럴 호출은 비용/잔여량 의미를 읽는 사람이 혼동하기 쉽습니다. 테스트 의도를 고정하려면 명시 변수로 분리하는 편이 안전합니다.
가독성 개선 예시
- LocalDateTime resetAt = LocalDateTime.of(2026, 4, 16, 18, 0); - - metrics.recordRateLimit(3, 120, resetAt); + LocalDateTime resetAt = LocalDateTime.of(2026, 4, 16, 18, 0); + int cost = 3; + int remaining = 120; + + metrics.recordRateLimit(cost, remaining, resetAt); - assertThat(metrics.getRemaining()).isEqualTo(120); + assertThat(metrics.getRemaining()).isEqualTo(remaining); assertThat(metrics.getResetAtFormatted()).isEqualTo("2026-04-16T18:00"); - assertThat(registry.get("github_api_cost_total").counter().count()).isEqualTo(3.0); - assertThat(registry.get("github_api_remaining").gauge().value()).isEqualTo(120.0); + assertThat(registry.get("github_api_cost_total").counter().count()).isEqualTo((double) cost); + assertThat(registry.get("github_api_remaining").gauge().value()).isEqualTo((double) remaining);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/test/java/com/gitranker/api/infrastructure/github/GitHubApiMetricsTest.java` around lines 19 - 26, In GitHubApiMetricsTest, make the meaning of the literals passed to metrics.recordRateLimit(...) explicit by introducing named local variables (e.g., int cost = 3; int remaining = 120;) and use those when calling recordRateLimit(cost, remaining, resetAt) and in the subsequent assertions; this clarifies the intent of the test and avoids ambiguity when referencing metrics.getRemaining(), registry.get("github_api_cost_total") and registry.get("github_api_remaining") in the assertions.src/test/java/com/gitranker/api/domain/ranking/RankingServiceTest.java (1)
85-95: 신규 empty-page 테스트에도 저장소 상호작용 검증을 맞춰주세요.동일 파일의 다른 테스트와 일관되게 repository 호출/추가 상호작용 부재까지 확인하면 회귀 탐지력이 더 좋아집니다.
일관성 보강 예시
assertThat(rankingList.pageInfo().totalElements()).isEqualTo(41); assertThat(rankingList.pageInfo().totalPages()).isEqualTo(3); assertThat(rankingList.pageInfo().isLast()).isTrue(); + verify(userRepository).findAllByOrderByScoreValueDesc(pageRequest); + verifyNoMoreInteractions(userRepository);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/test/java/com/gitranker/api/domain/ranking/RankingServiceTest.java` around lines 85 - 95, The test in RankingServiceTest that calls rankingService.getRankingList(2, null) sets up an empty PageImpl but does not verify repository interactions; update the test to assert the repository was called and no extra calls were made by adding verification for userRepository.findAllByOrderByScoreValueDesc(pageRequest) (using the same pageRequest used in the when) and a subsequent verifyNoMoreInteractions or verifyNoInteractions for other mocks to match the style of the other tests and catch regressions.src/test/java/com/gitranker/api/domain/log/ActivityLogServiceTest.java (1)
148-163:diff유지 검증을 전체 필드로 확장하면 테스트 의도가 더 명확해집니다.Line 161-162는 일부
diff필드만 확인합니다. 테스트명/의도(“diff 유지”)와 맞추려면diffIssueCount,diffPrCount,diffMergedPrCount도 함께 검증하는 편이 안전합니다.🔍 제안 diff
assertThat(baselineLog.getDiffCommitCount()).isZero(); + assertThat(baselineLog.getDiffIssueCount()).isZero(); + assertThat(baselineLog.getDiffPrCount()).isZero(); + assertThat(baselineLog.getDiffMergedPrCount()).isZero(); assertThat(baselineLog.getDiffReviewCount()).isZero();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/test/java/com/gitranker/api/domain/log/ActivityLogServiceTest.java` around lines 148 - 163, The test updatesBaselineLogWithoutTouchingDiff in ActivityLogServiceTest only asserts diffCommitCount and diffReviewCount remain zero; extend the "diff 유지" verification to assert baselineLog.getDiffIssueCount(), baselineLog.getDiffPrCount(), and baselineLog.getDiffMergedPrCount() are also zero so all diff-related fields are validated after calling activityLogService.updateBaselineLog.src/test/java/com/gitranker/api/domain/log/ActivityLogOrchestratorTest.java (1)
55-55: 날짜 검증 시LocalDate.now()재호출은 플래키 가능성이 있습니다.Line 55는 검증 시점에
LocalDate.now()를 다시 호출합니다. 테스트 본문에서 생성한today변수를 재사용하면 자정 경계에서의 간헐 실패를 줄일 수 있습니다.🧪 제안 diff
void skipsBaselineLogWhenNotProvidedForNewUser() { User user = user("alice"); ActivityStatistics totalStats = stats(10, 2, 3, 4, 5); + LocalDate today = LocalDate.now(); activityLogOrchestrator.createLogsForNewUser(user, totalStats, null); verify(activityLogService, never()).saveBaselineLog(any(User.class), any(ActivityStatistics.class), any(LocalDate.class)); - verify(activityLogService).saveActivityLog(user, totalStats, ActivityStatistics.empty(), LocalDate.now()); + verify(activityLogService).saveActivityLog(user, totalStats, ActivityStatistics.empty(), today); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/test/java/com/gitranker/api/domain/log/ActivityLogOrchestratorTest.java` at line 55, The test re-calls LocalDate.now() in the verify assertion which can be flaky around midnight; update the assertion in ActivityLogOrchestratorTest to reuse the test's existing today variable (the one created earlier in the test) instead of calling LocalDate.now() again so the verified call to activityLogService.saveActivityLog(user, totalStats, ActivityStatistics.empty(), ...) uses the stable today value.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/test/java/com/gitranker/api/batch/metrics/BatchMetricsTest.java`:
- Around line 39-50: The test currently only calls recordItemsProcessed and
recordItemsSkipped once so it won't detect non-accumulating implementations;
update the test in BatchMetricsTest to call BatchMetrics.recordItemsProcessed
and recordItemsSkipped multiple times (e.g., two calls with different values)
and then assert that the registry counters "batch_items_processed_total" and
"batch_items_skipped_total" reflect the summed totals (verify
registry.get(...).counter().count() equals the combined values) to ensure true
accumulation behavior.
In
`@src/test/java/com/gitranker/api/batch/processor/ScoreRecalculationProcessorTest.java`:
- Around line 79-82: The test calls LocalDate.now() repeatedly which can yield
different values around midnight/year boundaries; capture LocalDate today (and
currentYear via today.getYear()) once at the top of the test and reuse it for
all stubs and assertions (e.g. replace repeated
LocalDate.of(LocalDate.now().getYear(), 1, 1) calls used in
activityLogRepository.findTopByUserAndActivityDateLessThanOrderByActivityDateDesc
stubs and the other occurrences referenced in the comment ranges) so both the
stubbed inputs and expected values use the same deterministic date instance.
In `@src/test/java/com/gitranker/api/batch/scheduler/BatchSchedulerTest.java`:
- Around line 50-53: The test expectations in BatchSchedulerTest are mismatched
with BatchScheduler: the scheduler sets a "startTime" (Long) parameter but the
test asserts a "runTime" LocalDateTime; update the assertion around the
ArgumentCaptor<JobParameters> (used with
verify(jobLauncher).run(eq(dailyScoreRecalculationJob), captor.capture())) to
check for the "startTime" parameter instead (e.g., use
captor.getValue().getLong("startTime") and assert it is not null/positive) and
leave the LogContext assertion as-is; this aligns the test with the
BatchScheduler behavior.
In `@src/test/java/com/gitranker/api/domain/log/ActivityLogOrchestratorTest.java`:
- Line 93: 현재 검증은 특정 인자 조합(todayLog, totalStats)만 금지하므로 다른 인자들로
updateBaselineLog가 호출되면 테스트가 통과할 수 있습니다; ActivityLogOrchestratorTest에서
verify(activityLogService, never()).updateBaselineLog(todayLog, totalStats) 대신
updateBaselineLog 메서드 호출 자체를 금지하도록 verify(activityLogService,
never()).updateBaselineLog(any(), any()) (또는 verify(activityLogService,
times(0)).updateBaselineLog(any(), any()))로 바꿔 메서드 호출 여부만 검증하도록 수정하세요.
In `@src/test/java/com/gitranker/api/domain/user/UserTest.java`:
- Around line 33-46: Test updatesOnlyChangedProfileFields() is missing an
assertion that updatedAt remains unchanged when updateProfile is called with
identical values; modify the test to capture the timestamp before the
"unchanged" call (use User.getUpdatedAt()), call user.updateProfile(...) for the
unchanged case, then assert that user.getUpdatedAt() is equal to that pre-call
timestamp, and only after that perform the "changed" call and assert updatedAt
was advanced; reference the test method updatesOnlyChangedProfileFields(), the
User.updateProfile(...) calls, and User.getUpdatedAt() when adding these
assertions.
In
`@src/test/java/com/gitranker/api/infrastructure/github/GitHubGraphQLClientTest.java`:
- Around line 175-180: The assertions for the final token rate-limit are too
loose — replace the isIn checks with exact equality checks for the expected
post-merge values so the test fails if a stale (first-response) value is saved.
Update the assertions around remainingCaptor and resetCaptor used with
apiMetrics.recordRateLimit and tokenPool.updateTokenState to
assertThat(remainingCaptor.getValue()).isEqualTo(<expectedMergedRemaining>) and
assertThat(resetCaptor.getValue()).isEqualTo(mergedResetAt) (or the single
expected reset value), ensuring the test verifies the precise final
remaining/reset values after the second call.
In
`@src/test/java/com/gitranker/api/infrastructure/github/token/GitHubTokenPoolTest.java`:
- Around line 45-47: The test sets a token remaining value equal to the
threshold, so rotation won't occur; update the test so the scenario is truly
"below threshold" by calling pool.updateTokenState("token-a", <value less than
threshold>, LocalDateTime.now().plusMinutes(10)) (e.g., threshold-1) so that
pool.getToken() returns "token-b" as asserted; locate the call to
updateTokenState and adjust the remaining parameter accordingly, ensuring the
threshold constant used by the pool is considered.
---
Nitpick comments:
In
`@src/test/java/com/gitranker/api/batch/listener/UserScoreCalculationSkipListenerTest.java`:
- Around line 33-34: Replace repeated string literals in
UserScoreCalculationSkipListenerTest by introducing private static final
constants (e.g., JOB_NAME_DAILY_SCORE = "DailyScoreRecalculationJob" and
UNKNOWN_USER_ID = "UNKNOWN_USER") at the top of the test class and use those
constants wherever the literals appear (including the other occurrences
currently used in assertions/setup), ensuring all occurrences in methods that
reference the job name or user id (the repeated uses around the existing
assertions and test setups) are updated to the new constants for easier
maintenance.
In `@src/test/java/com/gitranker/api/domain/auth/service/AuthServiceTest.java`:
- Around line 131-140: The test currently only asserts the thrown
BusinessException for authService.logout; also verify no side effects occur by
asserting that refresh token removal and cookie/header cleanup are not invoked:
after calling logout(...) in the throwsWhenLogoutTokenDoesNotExist test, add
Mockito verifications to ensure refreshTokenRepository.delete and/or
refreshTokenRepository.deleteById are never called and
HttpServletResponse.addCookie and HttpServletResponse.setHeader are never called
(use the mocked HttpServletResponse passed into authService.logout) so the test
fails if any deletion or cookie/header modifications happen unexpectedly.
In `@src/test/java/com/gitranker/api/domain/log/ActivityLogOrchestratorTest.java`:
- Line 55: The test re-calls LocalDate.now() in the verify assertion which can
be flaky around midnight; update the assertion in ActivityLogOrchestratorTest to
reuse the test's existing today variable (the one created earlier in the test)
instead of calling LocalDate.now() again so the verified call to
activityLogService.saveActivityLog(user, totalStats, ActivityStatistics.empty(),
...) uses the stable today value.
In `@src/test/java/com/gitranker/api/domain/log/ActivityLogServiceTest.java`:
- Around line 148-163: The test updatesBaselineLogWithoutTouchingDiff in
ActivityLogServiceTest only asserts diffCommitCount and diffReviewCount remain
zero; extend the "diff 유지" verification to assert
baselineLog.getDiffIssueCount(), baselineLog.getDiffPrCount(), and
baselineLog.getDiffMergedPrCount() are also zero so all diff-related fields are
validated after calling activityLogService.updateBaselineLog.
In `@src/test/java/com/gitranker/api/domain/ranking/RankingServiceTest.java`:
- Around line 85-95: The test in RankingServiceTest that calls
rankingService.getRankingList(2, null) sets up an empty PageImpl but does not
verify repository interactions; update the test to assert the repository was
called and no extra calls were made by adding verification for
userRepository.findAllByOrderByScoreValueDesc(pageRequest) (using the same
pageRequest used in the when) and a subsequent verifyNoMoreInteractions or
verifyNoInteractions for other mocks to match the style of the other tests and
catch regressions.
In
`@src/test/java/com/gitranker/api/domain/user/service/UserRegistrationServiceTest.java`:
- Around line 108-123: Add an assertion that the returned RegisterUserResponse
preserves the existing user's email: after calling
userRegistrationService.register(attributes),
assertThat(response.email()).isEqualTo(existingUser.getEmail()) (or
assertThat(response.email()).isNull() if the fixture sets null), so the test
verifies the email is unchanged in UserRegistrationServiceTest alongside the
existing checks for updateProfile and gitHubActivityService calls.
In
`@src/test/java/com/gitranker/api/infrastructure/github/GitHubApiMetricsTest.java`:
- Around line 19-26: In GitHubApiMetricsTest, make the meaning of the literals
passed to metrics.recordRateLimit(...) explicit by introducing named local
variables (e.g., int cost = 3; int remaining = 120;) and use those when calling
recordRateLimit(cost, remaining, resetAt) and in the subsequent assertions; this
clarifies the intent of the test and avoids ambiguity when referencing
metrics.getRemaining(), registry.get("github_api_cost_total") and
registry.get("github_api_remaining") in the assertions.
In
`@src/test/java/com/gitranker/api/infrastructure/github/token/TokenStateTest.java`:
- Around line 26-27: In TokenStateTest, replace the time-dependent Instant.now()
usage (the resetAt variable and the other Instant.now() usages around lines
39–41) with a fixed Instant constant (e.g. a private static final Instant
FIXED_INSTANT) and derive offsets from that constant (use
FIXED_INSTANT.plusSeconds(...) where offsets are needed) so tests become
deterministic; update any assertions that referenced the previous dynamic times
to use the fixed Instant-based values.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: f50e6a1c-1392-4523-98e7-2dcc041c3d62
📒 Files selected for processing (44)
src/test/java/com/gitranker/api/batch/listener/BatchProgressListenerTest.javasrc/test/java/com/gitranker/api/batch/listener/GitHubCostListenerTest.javasrc/test/java/com/gitranker/api/batch/listener/UserScoreCalculationSkipListenerTest.javasrc/test/java/com/gitranker/api/batch/metrics/BatchMetricsTest.javasrc/test/java/com/gitranker/api/batch/processor/ScoreRecalculationProcessorTest.javasrc/test/java/com/gitranker/api/batch/reader/UserItemReaderTest.javasrc/test/java/com/gitranker/api/batch/scheduler/BatchSchedulerTest.javasrc/test/java/com/gitranker/api/batch/strategy/ActivityUpdateContextTest.javasrc/test/java/com/gitranker/api/batch/strategy/FullActivityUpdateStrategyTest.javasrc/test/java/com/gitranker/api/batch/strategy/IncrementalActivityUpdateStrategyTest.javasrc/test/java/com/gitranker/api/batch/tasklet/RankingRecalculationTaskletTest.javasrc/test/java/com/gitranker/api/batch/writer/UserItemWriterTest.javasrc/test/java/com/gitranker/api/domain/auth/service/AuthServiceTest.javasrc/test/java/com/gitranker/api/domain/badge/BadgeFormatterTest.javasrc/test/java/com/gitranker/api/domain/badge/BadgeServiceTest.javasrc/test/java/com/gitranker/api/domain/badge/SvgBadgeRendererTest.javasrc/test/java/com/gitranker/api/domain/log/ActivityLogOrchestratorTest.javasrc/test/java/com/gitranker/api/domain/log/ActivityLogServiceTest.javasrc/test/java/com/gitranker/api/domain/log/ActivityLogTest.javasrc/test/java/com/gitranker/api/domain/ranking/RankingRecalculationServiceTest.javasrc/test/java/com/gitranker/api/domain/ranking/RankingServiceTest.javasrc/test/java/com/gitranker/api/domain/user/UserTest.javasrc/test/java/com/gitranker/api/domain/user/service/UserDeletionServiceTest.javasrc/test/java/com/gitranker/api/domain/user/service/UserPersistenceServiceTest.javasrc/test/java/com/gitranker/api/domain/user/service/UserQueryServiceTest.javasrc/test/java/com/gitranker/api/domain/user/service/UserRefreshServiceTest.javasrc/test/java/com/gitranker/api/domain/user/service/UserRegistrationServiceTest.javasrc/test/java/com/gitranker/api/domain/user/vo/ActivityStatisticsTest.javasrc/test/java/com/gitranker/api/domain/user/vo/RankInfoTest.javasrc/test/java/com/gitranker/api/domain/user/vo/ScoreTest.javasrc/test/java/com/gitranker/api/global/util/TimeUtilsTest.javasrc/test/java/com/gitranker/api/infrastructure/github/GitHubActivityServiceTest.javasrc/test/java/com/gitranker/api/infrastructure/github/GitHubApiErrorHandlerTest.javasrc/test/java/com/gitranker/api/infrastructure/github/GitHubApiMetricsTest.javasrc/test/java/com/gitranker/api/infrastructure/github/GitHubDataMapperTest.javasrc/test/java/com/gitranker/api/infrastructure/github/GitHubGraphQLClientTest.javasrc/test/java/com/gitranker/api/infrastructure/github/dto/GitHubActivitySummaryTest.javasrc/test/java/com/gitranker/api/infrastructure/github/dto/GitHubAllActivitiesResponseTest.javasrc/test/java/com/gitranker/api/infrastructure/github/dto/GitHubGraphQLRequestTest.javasrc/test/java/com/gitranker/api/infrastructure/github/dto/GitHubNodeUserResponseTest.javasrc/test/java/com/gitranker/api/infrastructure/github/dto/GitHubUserInfoResponseTest.javasrc/test/java/com/gitranker/api/infrastructure/github/token/GitHubTokenPoolTest.javasrc/test/java/com/gitranker/api/infrastructure/github/token/TokenStateTest.javasrc/test/java/com/gitranker/api/infrastructure/github/util/GraphQLQueryBuilderTest.java
- Asia/Seoul 고정 zone 상수를 테스트에 재사용 - threshold 회전 케이스를 현재 시각 대신 고정된 미래 시각으로 검증 - UTC 환경으로 clean test를 재현해 CI 실패 원인 제거
요약
검증
./gradlew test --tests 'com.gitranker.api.batch.*'./gradlew test --tests 'com.gitranker.api.infrastructure.github.*'./gradlew testCloses #88
Summary by CodeRabbit
릴리스 노트