Visitar URL original
Add comprehensive test coverage for database queries and API endpoints by cwchanap · Pull Request #25 · cwchanap/cetus · GitHub
Skip to content

Add comprehensive test coverage for database queries and API endpoints - #25

Merged
cwchanap merged 5 commits into
mainfrom
claude/improve-test-coverage-KIbK4
Mar 12, 2026
Merged

cwchanap merged 5 commits into
mainfrom
claude/improve-test-coverage-KIbK4

Conversation

@cwchanap

@cwchanap cwchanap commented Mar 11, 2026 •

Copy link
Copy Markdown
Owner

Summary

This PR adds extensive test coverage for database query functions and API endpoints related to user stats, achievements, login rewards, and challenges. It includes 526 new lines of tests across multiple test files, ensuring robust validation of core functionality.

Key Changes

Database Query Tests (src/lib/server/db/queries.test.ts)

  • Added test suites for 8 new database query functions:
    • getUserStats - Tests null handling, distinct game counting, and error scenarios
    • getUserRecentScores - Tests pagination, default limits, and error handling
    • getUserBestScore - Tests score retrieval and null cases
    • getUserBestScoreForGame - Tests score conversion (null → 0)
    • hasUserEarnedAchievement - Tests achievement existence checks
    • awardAchievement - Tests achievement awarding with duplicate prevention
    • getUserAchievements - Tests achievement list retrieval
    • getAllUserIds - Tests user ID collection
    • getActiveUserIdsBetween - Tests date range filtering
    • getGameLeaderboard - Tests leaderboard generation with anonymous user handling

Login Reward Service Tests (src/lib/services/loginRewardService.test.ts)

  • Added comprehensive test suite for milestone badge logic in claimDailyLoginReward:
    • Tests 7-day streak milestone achievement awarding
    • Tests duplicate achievement prevention
    • Tests error handling during achievement award
    • Tests level-up detection and reporting
    • Tests various error conditions (already claimed, claim failure)

API Endpoint Tests (New Files)

  • src/pages/api/challenges/index.test.ts - Tests GET /api/challenges endpoint

    • Authentication validation
    • Challenge data retrieval
    • XP progress calculations
    • Error handling
  • src/pages/api/challenges/xp.test.ts - Tests GET /api/challenges/xp endpoint

    • XP and level data retrieval
    • Progress calculation
    • Max level reporting
  • src/pages/api/login-rewards/index.test.ts - Tests GET /api/login-rewards endpoint

    • Login reward status retrieval
    • Authentication checks
  • src/pages/api/login-rewards/claim.test.ts - Tests POST /api/login-rewards/claim endpoint

    • Reward claiming functionality
    • Error responses for already-claimed rewards
    • Level-up reporting

Settings API Tests (src/pages/api/settings/index.test.ts)

  • Added tests for JSON parsing error handling:
    • Malformed JSON (SyntaxError) returns 400
    • Non-SyntaxError exceptions propagate as 500
    • Challenge reminders preference updates

Notable Implementation Details

  • All tests use Vitest mocking framework with proper mock setup/teardown
  • Database query tests validate both success and error paths
  • API endpoint tests verify authentication, request handling, and response formatting
  • Tests include edge cases like null values, empty arrays, and database errors
  • Milestone badge logic tests verify the complete flow from streak completion to achievement award

https://claude.ai/code/session_012mRgqn64YXTkQbcs97r37c

Summary by CodeRabbit

  • Tests
    • Added comprehensive unit tests for login rewards, challenges endpoints, XP endpoints, and settings API (covering success, error, auth, and edge cases).
    • Added integration tests validating database query behavior against an in-memory SQLite instance.
    • Expanded mocks and sequencing to cover achievement/milestone badge flows, leveling, and XP calculations.

- Add tests for GET /api/challenges and GET /api/challenges/xp endpoints
- Add tests for GET /api/login-rewards and POST /api/login-rewards/claim endpoints
- Add milestone badge tests to loginRewardService (lines 262-281 coverage)
- Fix settings API tests: cover SyntaxError JSON parse path and challenge_reminders field
- Add query tests for getUserStats, getUserRecentScores, getUserBestScore,
  getUserBestScoreForGame, hasUserEarnedAchievement, awardAchievement,
  getUserAchievements, getAllUserIds, getActiveUserIdsBetween, getGameLeaderboard

Test count: 1073 → 1130 (+57 tests across 56 test files)

https://claude.ai/code/session_012mRgqn64YXTkQbcs97r37c
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@vercel

vercel Bot commented Mar 11, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
cetus Ready Ready Preview, Comment Mar 12, 2026 9:19am

@coderabbitai

coderabbitai Bot commented Mar 11, 2026 •

Copy link
Copy Markdown

Warning

Rate limit exceeded

@cwchanap has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 26 minutes and 51 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a8381b25-0fc5-473a-a13c-104f9087a28c

📥 Commits

Reviewing files that changed from the base of the PR and between 9b401f3 and 6a13214.

📒 Files selected for processing (2)
  • src/lib/server/db/queries.integration.test.ts
  • src/pages/api/settings/index.test.ts
📝 Walkthrough

Walkthrough

Adds extensive test coverage: unit tests for login rewards, challenges/XP, settings API, and an integration suite exercising DB query functions against an in-memory SQLite instance. All changes are tests-only with no public API signature alterations.

Changes

Cohort / File(s) Summary
Login Rewards tests
src/lib/services/loginRewardService.test.ts, src/pages/api/login-rewards/claim.test.ts, src/pages/api/login-rewards/index.test.ts
New and extended tests for claiming daily login rewards, milestone badge award flows (mocks for hasUserEarnedAchievement / awardAchievement), success/failure/error paths, authentication, and API response validation.
Challenges & XP tests
src/pages/api/challenges/index.test.ts, src/pages/api/challenges/xp.test.ts
New tests for GET /api/challenges and GET /api/challenges/xp covering auth, response shape, XP/level calculations, xpToNextLevel edge cases, streaks, and error handling; verifies service/query invocations.
Settings tests
src/pages/api/settings/index.test.ts
Adds global beforeEach mock reset and tests for JSON parse error handling (SyntaxError vs other), plus preference update tests for challenge_reminders.
Database integration tests
src/lib/server/db/queries.integration.test.ts
Large integration test suite using in-memory Kysely/SQLite: seeds and validates queries for user stats, recent/best scores, achievements (hasUserEarnedAchievement, awardAchievement), leaderboards, and active/user lists across edge cases.
Misc (imports/fixtures)
package.json
Manifest touched (small change) to support tests; no public API signature changes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

codex

Poem

🐰 I hopped through mocks and memory-DB,

Stubs and seeds arranged with glee.
Assertions chitter, tests take flight,
Badges bloom in morning light.
Hop—coverage grows, snug as can be.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: adding comprehensive test coverage for database queries and API endpoints, which aligns with all files modified in the pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/improve-test-coverage-KIbK4

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.

@codecov

codecov Bot commented Mar 11, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/pages/api/settings/index.test.ts (1)

210-232: Consider adding assertion for getUserPreferences call for consistency.

The test validates challenge_reminders updates correctly, but unlike the similar success test (lines 172-176), it doesn't assert that getUserPreferences was called after the update. This is a minor consistency gap.

♻️ Suggested addition for consistency
             expect(response.status).toBe(200)
             expect(data.success).toBe(true)
             expect(updateUserPreferences).toHaveBeenCalledWith(mockUserId, {
                 challenge_reminders: false,
             })
+            expect(getUserPreferences).toHaveBeenCalledWith(mockUserId)
         })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/api/settings/index.test.ts` around lines 210 - 232, Add the missing
assertion that verifies getUserPreferences was called after a successful update
in the test for challenge_reminders; specifically, in the it('should update
challenge_reminders when provided', ...) case assert that getUserPreferences was
called with mockUserId (the same check used in the similar success test),
placing the expect(getUserPreferences).toHaveBeenCalledWith(mockUserId) after
the POST call and before finishing the test.
src/pages/api/challenges/xp.test.ts (1)

37-41: Mock return type is missing currentLevel property.

Per the context snippet from src/lib/challenges.ts:251-270, getXPProgress() returns { currentLevel, currentLevelXP, nextLevelXP, progress }. While the current implementation doesn't use currentLevel, including it in the mock would make the test more robust against future changes and removes the need for as any.

Proposed fix
         vi.mocked(getXPProgress).mockReturnValue({
+            currentLevel: 3,
             progress: 20,
             currentLevelXP: 250,
             nextLevelXP: 500,
-        } as any)
+        })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/api/challenges/xp.test.ts` around lines 37 - 41, The mock for
getXPProgress in the test is missing the currentLevel property and uses a cast
to any; update the mock return object used in
vi.mocked(getXPProgress).mockReturnValue to include currentLevel (e.g.,
currentLevel: 1) alongside progress, currentLevelXP, and nextLevelXP so the
shape matches the real return from getXPProgress and remove the unnecessary type
coercion.
src/lib/services/loginRewardService.test.ts (1)

432-432: Mock return type should match actual function signature.

Per the context snippet from src/lib/server/db/queries.ts:861-896, awardAchievement returns Promise<boolean>. The mock should resolve to true instead of undefined.

Proposed fix
-        vi.mocked(awardAchievement).mockResolvedValue(undefined as any)
+        vi.mocked(awardAchievement).mockResolvedValue(true)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/services/loginRewardService.test.ts` at line 432, The test mock for
awardAchievement returns undefined but the real function signature returns
Promise<boolean>; update the mock in loginRewardService.test (the
vi.mocked(awardAchievement) call) to resolve a boolean (e.g., change
mockResolvedValue(undefined as any) to mockResolvedValue(true)) so the mocked
return type matches awardAchievement's Promise<boolean> signature and prevents
type/runtime mismatches.
🤖 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/lib/server/db/queries.test.ts`:
- Around line 758-1279: Tests in this file currently mock the file-level db
client (db.selectFrom / db.insertInto) which only asserts the Kysely call chain
and won't catch real SQL/table/column errors; replace these mocked usages by
spinning up an in-memory SQLite Kysely instance and run the query helpers
against it: create a test-only Kysely client, run migrations or create the
minimal tables, seed rows for each suite (e.g., for getUserStats,
getUserRecentScores, getUserBestScore, awardAchievement, getUserAchievements,
getAllUserIds, getActiveUserIdsBetween, getGameLeaderboard), and call the actual
functions (getUserStats, getUserRecentScores, getUserBestScore,
getUserBestScoreForGame, hasUserEarnedAchievement, awardAchievement,
getUserAchievements, getAllUserIds, getActiveUserIdsBetween, getGameLeaderboard)
without mocking db.selectFrom/insertInto so assertions validate real results;
ensure each describe block sets up/tears down the in-memory DB (seed rows
matching assertions and clear between tests) and remove
vi.mocked(db.selectFrom)/db.insertInto stubs from these tests.
- Around line 776-812: The test for getUserStats incorrectly allows the
distinct-game-count behavior to pass even if distinct() is removed because
mockGamesQuery.execute returns already-unique game_id rows; update the test to
either include duplicate game_id entries in mockGamesQuery.execute (e.g.,
include two { game_id: 'tetris' } rows so total_games_played should be 3 only if
deduplication occurs) or add an assertion that mockGamesQuery.distinct was
called (e.g., expect(mockGamesQuery.distinct).toHaveBeenCalled()) to ensure the
distinct() call is exercised.

---

Nitpick comments:
In `@src/lib/services/loginRewardService.test.ts`:
- Line 432: The test mock for awardAchievement returns undefined but the real
function signature returns Promise<boolean>; update the mock in
loginRewardService.test (the vi.mocked(awardAchievement) call) to resolve a
boolean (e.g., change mockResolvedValue(undefined as any) to
mockResolvedValue(true)) so the mocked return type matches awardAchievement's
Promise<boolean> signature and prevents type/runtime mismatches.

In `@src/pages/api/challenges/xp.test.ts`:
- Around line 37-41: The mock for getXPProgress in the test is missing the
currentLevel property and uses a cast to any; update the mock return object used
in vi.mocked(getXPProgress).mockReturnValue to include currentLevel (e.g.,
currentLevel: 1) alongside progress, currentLevelXP, and nextLevelXP so the
shape matches the real return from getXPProgress and remove the unnecessary type
coercion.

In `@src/pages/api/settings/index.test.ts`:
- Around line 210-232: Add the missing assertion that verifies
getUserPreferences was called after a successful update in the test for
challenge_reminders; specifically, in the it('should update challenge_reminders
when provided', ...) case assert that getUserPreferences was called with
mockUserId (the same check used in the similar success test), placing the
expect(getUserPreferences).toHaveBeenCalledWith(mockUserId) after the POST call
and before finishing the test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 78d100d0-4b22-41eb-a881-7e600b083db0

📥 Commits

Reviewing files that changed from the base of the PR and between 148b3d8 and 84baeb6.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • src/lib/server/db/queries.test.ts
  • src/lib/services/loginRewardService.test.ts
  • src/pages/api/challenges/index.test.ts
  • src/pages/api/challenges/xp.test.ts
  • src/pages/api/login-rewards/claim.test.ts
  • src/pages/api/login-rewards/index.test.ts
  • src/pages/api/settings/index.test.ts

Comment thread src/lib/server/db/queries.test.ts Outdated
Comment thread src/lib/server/db/queries.test.ts Outdated
- Replace mocked-db tests for getUserStats, getUserRecentScores, getUserBestScore,
  getUserBestScoreForGame, hasUserEarnedAchievement, awardAchievement,
  getUserAchievements, getAllUserIds, getActiveUserIdsBetween, getGameLeaderboard
  with real in-memory SQLite Kysely tests in queries.integration.test.ts; these
  validate actual SQL behavior including distinct(), LEFT JOIN coalesce fallback,
  limit clamping, and user isolation
- getUserStats integration test seeds duplicate game_id rows to verify the
  distinct() deduplication is real and not incidental
- Fix awardAchievement mock in loginRewardService.test.ts: return true instead of
  undefined as any to match Promise<boolean> signature
- Add missing currentLevel field to getXPProgress mock in xp.test.ts and remove
  unnecessary 'as any' cast
- Add missing getUserPreferences assertion in settings challenge_reminders test

Test count: 1130 → 1136 (+6 net; integration tests replace previous mocked set)

https://claude.ai/code/session_012mRgqn64YXTkQbcs97r37c

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/pages/api/settings/index.test.ts (1)

15-16: Consider adding mock cleanup between tests.

The test suite doesn't reset mocks between tests. While each test explicitly sets mock return values, adding beforeEach(() => vi.clearAllMocks()) would ensure test isolation and prevent potential state leakage—particularly useful as the test suite grows.

♻️ Suggested addition after line 16
 describe('Settings API', () => {
     const mockUserId = 'test-user-123'
+
+    beforeEach(() => {
+        vi.clearAllMocks()
+    })

     const mockLocals = {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/api/settings/index.test.ts` around lines 15 - 16, Add a test-level
cleanup hook to the "Settings API" suite to avoid mock state leaking: inside the
describe block that defines mockUserId, add a beforeEach that calls
vi.clearAllMocks() so all mocks are reset before each test (ensuring tests are
isolated and do not rely on prior mock call history or return values).
src/lib/server/db/queries.integration.test.ts (2)

301-321: Use raw table assertions for awardAchievement.

Lines 306-320 verify awardAchievement() through hasUserEarnedAchievement() and getUserAchievements(), which are sibling helpers from the same module. If those helpers share the same filter or mapping bug, this suite still passes. Query user_achievements directly here so the award tests keep an independent oracle.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/server/db/queries.integration.test.ts` around lines 301 - 321, The
tests currently validate awardAchievement('u1','tetris_master') using sibling
helpers hasUserEarnedAchievement and getUserAchievements which can mask shared
bugs; instead, after calling awardAchievement (and after seedAchievement in the
duplicate test) run a direct query against the user_achievements table to assert
the row exists and that there is only one row for user_id 'u1' and
achievement_id 'tetris_master'. Update the second test to replace the
getUserAchievements/filter assertion with a raw DB query that counts rows where
user_id = 'u1' AND achievement_id = 'tetris_master' and assert count === 1, and
in the first test assert the direct table contains the new row rather than using
hasUserEarnedAchievement.

123-145: Type the seedUserStats fixture shape.

Record<string, unknown> lets misspelled keys silently fall back to defaults, and v hides what the object represents. A small typed fixture interface or Partial<...> plus a descriptive name makes schema drift obvious at compile time.

As per coding guidelines, **/*.{js,ts,jsx,tsx,py,java,go}: Write clear variable names that describe their purpose; src/lib/server/**/*.ts: Use Kysely for all database queries following established patterns in src/lib/server/db/queries.ts with proper TypeScript types for entities.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/server/db/queries.integration.test.ts` around lines 123 - 145, The
seedUserStats helper currently accepts overrides: Record<string, unknown> and
builds an untyped object v; replace that with a properly typed fixture shape
(e.g., use Partial<UserStats> or a dedicated interface like
UserStatsInsertOverride) so TS catches misspelled keys and schema drift, rename
v to a descriptive name such as stats or seedValues, and update the INSERT call
to consume the typed fields; follow the established Kysely entity/type
definitions used in src/lib/server/db/queries.ts to import the UserStats type
and ensure the function signature and local variable types reflect that typed
shape.
🤖 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/lib/server/db/queries.integration.test.ts`:
- Around line 116-120: Update the seedScore helper to accept an optional
createdAt parameter and use it in the INSERT so tests can control timestamps:
modify async function seedScore(userId: string, gameId: string, score: number)
to add a createdAt?: string | Date (or Timestamp) argument and include the
created_at column/value in the SQL INSERT when provided (fall back to the table
default when omitted) so tests for getUserRecentScores and
getActiveUserIdsBetween can assert precise ordering and in/out-of-range
behavior.

---

Nitpick comments:
In `@src/lib/server/db/queries.integration.test.ts`:
- Around line 301-321: The tests currently validate
awardAchievement('u1','tetris_master') using sibling helpers
hasUserEarnedAchievement and getUserAchievements which can mask shared bugs;
instead, after calling awardAchievement (and after seedAchievement in the
duplicate test) run a direct query against the user_achievements table to assert
the row exists and that there is only one row for user_id 'u1' and
achievement_id 'tetris_master'. Update the second test to replace the
getUserAchievements/filter assertion with a raw DB query that counts rows where
user_id = 'u1' AND achievement_id = 'tetris_master' and assert count === 1, and
in the first test assert the direct table contains the new row rather than using
hasUserEarnedAchievement.
- Around line 123-145: The seedUserStats helper currently accepts overrides:
Record<string, unknown> and builds an untyped object v; replace that with a
properly typed fixture shape (e.g., use Partial<UserStats> or a dedicated
interface like UserStatsInsertOverride) so TS catches misspelled keys and schema
drift, rename v to a descriptive name such as stats or seedValues, and update
the INSERT call to consume the typed fields; follow the established Kysely
entity/type definitions used in src/lib/server/db/queries.ts to import the
UserStats type and ensure the function signature and local variable types
reflect that typed shape.

In `@src/pages/api/settings/index.test.ts`:
- Around line 15-16: Add a test-level cleanup hook to the "Settings API" suite
to avoid mock state leaking: inside the describe block that defines mockUserId,
add a beforeEach that calls vi.clearAllMocks() so all mocks are reset before
each test (ensuring tests are isolated and do not rely on prior mock call
history or return values).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 366912f6-3702-4209-82cf-741d95509546

📥 Commits

Reviewing files that changed from the base of the PR and between 84baeb6 and 32db701.

📒 Files selected for processing (4)
  • src/lib/server/db/queries.integration.test.ts
  • src/lib/services/loginRewardService.test.ts
  • src/pages/api/challenges/xp.test.ts
  • src/pages/api/settings/index.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/pages/api/challenges/xp.test.ts

Comment thread src/lib/server/db/queries.integration.test.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR expands Vitest coverage across API routes and server-side services/DB queries related to settings, challenges, and login rewards, including a new SQLite-backed integration test suite for key query helpers.

Changes:

  • Added new API route test suites for challenges and login rewards endpoints.
  • Extended settings API tests to cover malformed JSON handling and challenge_reminders updates.
  • Added milestone badge logic tests for claimDailyLoginReward and introduced DB query integration tests using an in-memory SQLite instance.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/pages/api/settings/index.test.ts Adds POST coverage for malformed JSON handling and challenge_reminders preference updates.
src/pages/api/login-rewards/index.test.ts New tests for GET /api/login-rewards auth, success, and error handling.
src/pages/api/login-rewards/claim.test.ts New tests for POST /api/login-rewards/claim success and error mapping behavior.
src/pages/api/challenges/index.test.ts New tests for GET /api/challenges response shape and xpToNextLevel calculations.
src/pages/api/challenges/xp.test.ts New tests for GET /api/challenges/xp auth, response shaping, and error handling.
src/lib/services/loginRewardService.test.ts Adds unit tests for milestone badge awarding/duplication prevention/error handling and level-up detection.
src/lib/server/db/queries.integration.test.ts New integration tests exercising query behavior against an in-memory SQLite database.
bun.lock Lockfile update (adds configVersion).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/lib/server/db/queries.integration.test.ts Outdated
Comment thread src/pages/api/settings/index.test.ts Outdated
- seedScore: add optional createdAt parameter so tests can control timestamps
  for precise ordering and in/out-of-range assertions
- seedUserStats: replace Record<string, unknown> overrides with
  Partial<UserStatsUpdate> and rename local variable to seedValues for type
  safety; TS now catches misspelled keys and schema drift
- awardAchievement tests: replace hasUserEarnedAchievement/getUserAchievements
  indirect assertions with direct raw SQL COUNT queries against user_achievements
  to avoid masking shared bugs between the tested functions
- settings/index.test.ts: add beforeEach(() => vi.clearAllMocks()) to the
  top-level Settings API describe block to prevent mock state leaking between
  tests

https://claude.ai/code/session_012mRgqn64YXTkQbcs97r37c
- Seed an out-of-range score (year 3000) in getActiveUserIdsBetween test
  and assert that user is excluded, verifying the date predicate actually
  filters records rather than accepting everything in the wide range
- Rename 'should rethrow non-SyntaxError from JSON parsing' to
  'should return 500 when request.json throws a non-SyntaxError' to
  accurately reflect the observable behavior (outer catch returns 500,
  not a rethrow)

https://claude.ai/code/session_012mRgqn64YXTkQbcs97r37c

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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/lib/server/db/queries.integration.test.ts`:
- Around line 400-429: The test for getActiveUserIdsBetween currently uses a
wide epoch→far-future window and only checks deduplication; change it to
deterministically verify range filtering by seeding scores with explicit
timestamps (use seedScore with a timestamp parameter or an alternative helper)
for three users: one score strictly before the start, one score strictly inside
the start–end window, and one strictly after the end; call
getActiveUserIdsBetween with a tight start/end (e.g., fixed Date objects) and
assert the result contains only the in-range user ID, still deduplicates
multiple in-range scores for the same user, and excludes the out-of-range user
IDs. Ensure you reference and modify getActiveUserIdsBetween and seedScore
usages in the test to set explicit timestamps and add assertions for exclusion
of out-of-range IDs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b06b441d-619c-4e38-be81-8c4ef783285f

📥 Commits

Reviewing files that changed from the base of the PR and between 32db701 and 9b401f3.

📒 Files selected for processing (2)
  • src/lib/server/db/queries.integration.test.ts
  • src/pages/api/settings/index.test.ts

Comment thread src/lib/server/db/queries.integration.test.ts
…oundary tests

Use fixed Date windows (new Date(3e12)/new Date(5e12)) and explicit ISO
timestamps to cover all three boundary cases in a single test:
- u_before ('2024-06-01') excluded because '2' < '3000000000000' start
- u_inside ('4000-01-01', '4500-06-01') included and deduplicated to one ID
- u_after ('9999-01-01') excluded because '9' > '5000000000000' end

Adds a comment explaining the libsql Date→numeric-ms→TEXT lexicographic
comparison mechanism so the timestamp choices are self-documenting.

https://claude.ai/code/session_012mRgqn64YXTkQbcs97r37c
@cwchanap

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

ℹ️ 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".

@cwchanap
cwchanap merged commit c745679 into main Mar 12, 2026
8 checks passed

This branch was successfully deployed

1 active deployment
Preview — 6a132145 Deployed Mar 12, 2026 by vercel[bot]
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.

3 participants