🧪 QA: Add missing test for ComparativeProgressService#350
🧪 QA: Add missing test for ComparativeProgressService#350daggerstuff wants to merge 1 commit intostagingfrom
Conversation
Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
Reviewer's guide (collapsed on small PRs)Reviewer's GuideAdds a new Vitest unit test suite for ComparativeProgressService, targeting the insufficient data edge case to improve coverage and verify expected behavior. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
📝 WalkthroughWalkthroughAdded a new Vitest test suite for Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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.
- The test relies on
any(mockLogger,(service as any)), which reduces refactoring safety and can hide mistakes. - Stubbing
fetchUserProgressDatavia ananycast is brittle; consider stubbing at an injected dependency boundary or overriding aprotectedmethod in a test subclass. - Consider adding
afterEach(() => vi.restoreAllMocks())to avoid mock leakage as the suite grows.
Summary of changes
What changed
- Added a new Vitest unit test file:
src/lib/services/analytics/__tests__/ComparativeProgressService.test.ts. - The test covers the edge case where
analyzeProgress()has no user progress snapshots, asserting:result.userProgressSnapshotsis emptyresult.comparisonInsights.trend === "insufficient_data"
- Introduced a simple mocked logger (
info,error) and stubbed internal data retrieval viafetchUserProgressData.
|
|
||
| describe("ComparativeProgressService", () => { | ||
| let service: ComparativeProgressService | ||
| let mockLogger: any |
There was a problem hiding this comment.
Using any for mockLogger removes useful constraints and can hide real test mistakes (e.g., misspelling error/info or passing the wrong callable shape). Even in tests, prefer a minimal explicit type or satisfies so the mock stays aligned with what ComparativeProgressService expects.
Suggestion
Replace any with a small, explicit logger shape (or satisfies the service's logger type if it’s exported).
let mockLogger: { info: ReturnType<typeof vi.fn>; error: ReturnType<typeof vi.fn> }
beforeEach(() => {
mockLogger = {
info: vi.fn(),
error: vi.fn()
}
service = new ComparativeProgressService(mockLogger)
})If the real logger type is available, prefer:
const mockLogger = {
info: vi.fn(),
error: vi.fn()
} satisfies LoggerReply with "@CharlieHelps yes please" if you’d like me to add a commit with this change.
| }) | ||
|
|
||
| it("should return insufficient data when no user progress snapshots exist", async () => { | ||
| vi.spyOn(service as any, "fetchUserProgressData").mockResolvedValue([]) |
There was a problem hiding this comment.
Spying on an internal method via (service as any) makes the test brittle and weakens refactoring safety (renames/visibility changes won’t be caught cleanly). This also introduces additional any usage, which can mask incorrect stubbing.
Suggestion
Prefer stubbing at an injected dependency boundary (ideal), or make the data-fetch method protected and override it in a test subclass.
Example (if you can change visibility to protected):
class TestComparativeProgressService extends ComparativeProgressService {
protected override fetchUserProgressData() {
return Promise.resolve([])
}
}
beforeEach(() => {
service = new TestComparativeProgressService(mockLogger)
})At minimum, also ensure spies don’t leak across tests:
afterEach(() => vi.restoreAllMocks())Reply with "@CharlieHelps yes please" if you’d like me to add a commit with a safer stubbing approach.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a333600824
ℹ️ 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".
| metricName: "test-metric", | ||
| cohortId: "test-cohort", | ||
| dateRange: { startDate: "2023-01-01", endDate: "2023-01-31" } |
There was a problem hiding this comment.
Validate no-snapshot path with a non-null benchmark
Using metricName: "test-metric" makes fetchBenchmarkData return null in ComparativeProgressService, so the current assertions can still pass even if the early-return branch for empty snapshots is removed: generateInsights would still produce insufficient_data. This means the test does not actually protect the intended regression scenario and gives false confidence about the no-user-data shortcut path.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
Adds a Vitest unit test to cover an “insufficient data” edge case in ComparativeProgressService, improving confidence and coverage for analytics progress comparisons.
Changes:
- Added a new unit test verifying
analyzeProgress()returnstrend: 'insufficient_data'when no user progress snapshots are available. - Introduced test setup with a mocked logger and a stubbed
fetchUserProgressData()call to force the edge case.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import { describe, it, expect, vi, beforeEach } from "vitest" | ||
| import { ComparativeProgressService } from "../ComparativeProgressService" | ||
|
|
||
| describe("ComparativeProgressService", () => { |
There was a problem hiding this comment.
This test file uses double quotes, which is inconsistent with the repo’s standard single-quote formatting in TS/Vitest tests (e.g., AnalyticsService.test.ts). Running the repo formatter (oxfmt) / aligning to single quotes will keep formatting consistent and avoid churn in future formatting-only diffs.
|
|
||
| describe("ComparativeProgressService", () => { | ||
| let service: ComparativeProgressService | ||
| let mockLogger: any |
There was a problem hiding this comment.
mockLogger is typed as any, which makes refactors harder (e.g., changing the logger interface won’t surface type errors in tests). Consider typing it via the service constructor parameter type (e.g., ConstructorParameters<typeof ComparativeProgressService>[0]) or a locally declared logger type matching the constructor.
| let mockLogger: any | |
| let mockLogger: ConstructorParameters<typeof ComparativeProgressService>[0] |
| vi.spyOn(service as any, "fetchUserProgressData").mockResolvedValue([]) | ||
|
|
||
| const result = await service.analyzeProgress({ | ||
| anonymizedUserId: "test-user", | ||
| metricName: "test-metric", | ||
| cohortId: "test-cohort", | ||
| dateRange: { startDate: "2023-01-01", endDate: "2023-01-31" } | ||
| }) |
There was a problem hiding this comment.
This test uses service as any to spy on a private method. A narrower cast (e.g., to an object type that only exposes fetchUserProgressData) keeps TypeScript checking in place and reduces the chance of the test silently breaking if the method name/signature changes.
| vi.spyOn(service as any, "fetchUserProgressData").mockResolvedValue([]) | |
| const result = await service.analyzeProgress({ | |
| anonymizedUserId: "test-user", | |
| metricName: "test-metric", | |
| cohortId: "test-cohort", | |
| dateRange: { startDate: "2023-01-01", endDate: "2023-01-31" } | |
| }) | |
| const serviceWithFetch = service as Pick<ComparativeProgressService, "fetchUserProgressData"> | |
| vi.spyOn(serviceWithFetch, "fetchUserProgressData").mockResolvedValue([]) | |
| const result = await service.analyzeProgress({ | |
| anonymizedUserId: "test-user", | |
| metricName: "test-metric", | |
| cohortId: "test-cohort", | |
| dateRange: { startDate: "2023-01-01", endDate: "2023-01-31" } |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/lib/services/analytics/__tests__/ComparativeProgressService.test.ts (1)
2-2: Use@/alias for imports pointing tosrc/lib/.As per coding guidelines: "Use
@/alias for imports pointing tosrc/lib/(e.g.,import { aiService } from '@/lib')".Suggested fix
-import { ComparativeProgressService } from "../ComparativeProgressService" +import { ComparativeProgressService } from "@/lib/services/analytics/ComparativeProgressService"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/services/analytics/__tests__/ComparativeProgressService.test.ts` at line 2, The test import uses a relative path; update the import to use the project alias for src/lib by replacing the relative import of ComparativeProgressService with the aliased import (e.g., import { ComparativeProgressService } from '@/lib/...') so the test imports ComparativeProgressService via the "@/lib" alias rather than "../ComparativeProgressService"; locate the import statement referencing ComparativeProgressService in ComparativeProgressService.test.ts and switch it to the corresponding "@/lib/..." path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/lib/services/analytics/__tests__/ComparativeProgressService.test.ts`:
- Line 2: The test import uses a relative path; update the import to use the
project alias for src/lib by replacing the relative import of
ComparativeProgressService with the aliased import (e.g., import {
ComparativeProgressService } from '@/lib/...') so the test imports
ComparativeProgressService via the "@/lib" alias rather than
"../ComparativeProgressService"; locate the import statement referencing
ComparativeProgressService in ComparativeProgressService.test.ts and switch it
to the corresponding "@/lib/..." path.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 4e7e7371-f98c-49b8-bb4b-51aaa72bee26
📒 Files selected for processing (1)
src/lib/services/analytics/__tests__/ComparativeProgressService.test.ts
💡 What: Added missing unit test for ComparativeProgressService\n🎯 Why: Improves code coverage and ensures insufficient data edge case is handled\n✅ Verification: Passes successfully in Vitest
PR created automatically by Jules for task 8724582588193437195 started by @daggerstuff
Summary by Sourcery
Tests:
Summary by CodeRabbit