Skip to content

🧪 QA: Add missing test for ComparativeProgressService#350

Open
daggerstuff wants to merge 1 commit intostagingfrom
test/comparative-progress-12345-8724582588193437195
Open

🧪 QA: Add missing test for ComparativeProgressService#350
daggerstuff wants to merge 1 commit intostagingfrom
test/comparative-progress-12345-8724582588193437195

Conversation

@daggerstuff
Copy link
Copy Markdown
Owner

@daggerstuff daggerstuff commented Apr 2, 2026

💡 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:

  • Add a unit test for ComparativeProgressService covering the insufficient data edge case.

Summary by CodeRabbit

  • Tests
    • Added test coverage for progress analysis functionality to ensure accurate data handling and edge case scenarios.

Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pixelated Ready Ready Preview, Comment Apr 2, 2026 1:34am

@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 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 @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

Copilot AI review requested due to automatic review settings April 2, 2026 01:31
@charliecreates charliecreates bot requested a review from CharlieHelps April 2, 2026 01:31
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Apr 2, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adds a new Vitest unit test suite for ComparativeProgressService, targeting the insufficient data edge case to improve coverage and verify expected behavior.

File-Level Changes

Change Details Files
Add unit tests for ComparativeProgressService insufficient-data behavior.
  • Create a new Vitest test suite for ComparativeProgressService under the analytics services tests directory
  • Instantiate ComparativeProgressService with representative input data that exercises the insufficient-data edge case
  • Assert that the service returns the expected result (or throws/handles errors as designed) when provided with insufficient data
  • Ensure tests run under Vitest and integrate with the existing analytics test setup
src/lib/services/analytics/__tests__/ComparativeProgressService.test.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 2, 2026

📝 Walkthrough

Walkthrough

Added a new Vitest test suite for ComparativeProgressService that validates behavior when no user progress snapshots are available. The test mocks the service dependencies, stubs data fetching, and asserts the service returns empty snapshots with an insufficient data trend indicator.

Changes

Cohort / File(s) Summary
Test Suite
src/lib/services/analytics/__tests__/ComparativeProgressService.test.ts
Added new test case for ComparativeProgressService covering the no-snapshots scenario with mocked logger and stubbed data fetching method.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Poem

🐰 A test was born with care and grace,
To check when progress leaves no trace,
With mocks and stubs in place so neat,
The service's silence—bittersweet! 🎯✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly indicates the main change: adding a missing test for ComparativeProgressService, which aligns with the changeset that introduces a new test suite file.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/comparative-progress-12345-8724582588193437195

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
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown

@charliecreates charliecreates bot left a comment

Choose a reason for hiding this comment

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

  • The test relies on any (mockLogger, (service as any)), which reduces refactoring safety and can hide mistakes.
  • Stubbing fetchUserProgressData via an any cast is brittle; consider stubbing at an injected dependency boundary or overriding a protected method 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.userProgressSnapshots is empty
    • result.comparisonInsights.trend === "insufficient_data"
  • Introduced a simple mocked logger (info, error) and stubbed internal data retrieval via fetchUserProgressData.


describe("ComparativeProgressService", () => {
let service: ComparativeProgressService
let mockLogger: any
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 Logger

Reply 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([])
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 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".

Comment on lines +21 to +23
metricName: "test-metric",
cohortId: "test-cohort",
dateRange: { startDate: "2023-01-01", endDate: "2023-01-31" }
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

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() returns trend: '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.

Comment on lines +1 to +4
import { describe, it, expect, vi, beforeEach } from "vitest"
import { ComparativeProgressService } from "../ComparativeProgressService"

describe("ComparativeProgressService", () => {
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.

describe("ComparativeProgressService", () => {
let service: ComparativeProgressService
let mockLogger: any
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
let mockLogger: any
let mockLogger: ConstructorParameters<typeof ComparativeProgressService>[0]

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +24
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" }
})
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
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" }

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

@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.

🧹 Nitpick comments (1)
src/lib/services/analytics/__tests__/ComparativeProgressService.test.ts (1)

2-2: Use @/ alias for imports pointing to src/lib/.

As per coding guidelines: "Use @/ alias for imports pointing to src/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

📥 Commits

Reviewing files that changed from the base of the PR and between a08c8c9 and a333600.

📒 Files selected for processing (1)
  • src/lib/services/analytics/__tests__/ComparativeProgressService.test.ts

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 1 file

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