Skip to content

test: add comprehensive validate middleware unit tests - #689

Merged
LucasSantana-Dev merged 7 commits into
mainfrom
test/backend-validate-middleware
Apr 17, 2026
Merged

LucasSantana-Dev merged 7 commits into
mainfrom
test/backend-validate-middleware

Conversation

@LucasSantana-Dev

@LucasSantana-Dev LucasSantana-Dev commented Apr 17, 2026 •

Copy link
Copy Markdown
Owner

Summary

Adds comprehensive unit test coverage for the validate middleware.

Changes

  • validate.test.ts (new): Unit tests for validateBody, validateQuery, validateParams

Test Coverage

  • 100% of validate.ts paths
  • Valid and invalid input scenarios
  • Error handling and formatting

Related

Extracted from #678 validation work (now focusing on tests-only).

Summary by CodeRabbit

  • Bug Fixes

    • Improved input validation for query and URL parameters to strip unknown fields and ensure only validated data is processed.
  • Refactor

    • Updated validation schemas for moderation and management endpoints with enhanced parameter requirements.
  • Tests

    • Added unit tests for parameter validation middleware behavior and field-stripping logic.

@vercel

vercel Bot commented Apr 17, 2026 •

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
lucky Ready Ready Preview, Comment Apr 17, 2026 5:43pm

Request Review

@coderabbitai

coderabbitai Bot commented Apr 17, 2026 •

Copy link
Copy Markdown

Warning

Rate limit exceeded

@LucasSantana-Dev has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 48 minutes and 20 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 48 minutes and 20 seconds.

⌛ 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9bc8162b-de2a-4161-9af8-57a46b131416

📥 Commits

Reviewing files that changed from the base of the PR and between 0c94aae and f83f366.

📒 Files selected for processing (1)
  • packages/backend/src/middleware/validate.ts
📝 Walkthrough

Walkthrough

This PR modifies validation middleware and request schemas to enforce guild context alongside user identification in management and moderation endpoints. The validate middleware now strips unknown fields from request objects and reassigns validated data. Supporting unit and integration tests are updated accordingly.

Changes

Cohort / File(s) Summary
Validation Middleware Logic
packages/backend/src/middleware/validate.ts
Added post-validation mutation: iterates over request query/params keys, removes any keys absent from validated result, and merges coerced values back via Object.assign.
Schema Definitions
packages/backend/src/schemas/management.ts, packages/backend/src/schemas/moderation.ts
Redefined userIdParam and userCasesParam schemas to extend guildIdParam with userId field instead of aliasing commonUserIdParam, now enforcing both guild ID and user ID requirement.
Test Coverage
packages/backend/tests/unit/middleware/validate.test.ts
Added unit tests for validateQuery and validateParams middleware to verify field assignment, unknown field stripping, and optional field handling behavior.
Integration Test Cleanup
packages/backend/tests/integration/services/redisCaching.test.ts
Removed Jest mock for Prisma client JsonNull export.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

size/m

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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 'test: add comprehensive validate middleware unit tests' is directly related to the primary change. The PR primarily adds comprehensive unit tests for the validate middleware (39 lines of tests added), and while there are schema and middleware logic changes, the title accurately reflects the main focus established by the commit messages and PR objectives.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/backend-validate-middleware

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.

…asesParam/userIdParam schemas

- Assign validated query/params to req.query/req.params to strip unknown fields
- Fix moderation.ts userCasesParam schema to include guildId
- Fix management.ts userIdParam schema to include guildId
- All 775 tests now pass

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

🧹 Nitpick comments (2)
packages/backend/src/middleware/validate.ts (1)

33-38: Strip-then-merge logic is correct; one caveat on non-object schemas.

The in-place mutation pattern is the right approach — Express 5 exposes req.query as a getter, so reassignment would throw, whereas key-level deletion and Object.assign safely update the existing object. Since Zod object schemas strip unknown keys by default, result.data already lacks unknowns, so the delete loop on req.query is what actually enforces stripping at the HTTP-layer.

Minor robustness note: key in result.data assumes result.data is an object. If a caller ever passes a schema whose output is a primitive (e.g. a .transform(...) producing a string/number) to validateQuery/validateParams, this line will throw TypeError: Cannot use 'in' operator. Consider a guard like typeof result.data === 'object' && result.data !== null before the cleanup loop, or tighten the generic constraint to Schema<Record<string, unknown>> for query/params variants.

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

In `@packages/backend/src/middleware/validate.ts` around lines 33 - 38, The
delete-then-assign logic iterates keys on req.query and uses "key in
result.data", which will throw if result.data is a non-object; update the
cleanup to first guard that result.data is an object (e.g. check typeof
result.data === "object" && result.data !== null) before running the
Object.keys(req.query).forEach loop and Object.assign, or alternatively tighten
the schema/generic for validateQuery/validateParams to only accept object-shaped
outputs; locate the logic in validate.ts around req.query and result.data and
apply the guard or type constraint accordingly.
packages/backend/tests/unit/middleware/validate.test.ts (1)

67-86: Good coverage of the new mutate-and-strip behavior.

Optional enhancement: add a case that exercises coercion (e.g., z.object({ limit: z.coerce.number() }) with input { limit: '10' }) and asserts req.query.limit === 10. That captures the main user-visible benefit of writing result.data back onto req.query (type-coerced values reaching the route handler), which the current tests don't directly verify since the schema here keeps limit as a string.

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

In `@packages/backend/tests/unit/middleware/validate.test.ts` around lines 67 -
86, Add a new unit test that verifies coercion by defining a schema that uses
z.coerce.number() for limit (e.g., const coercingSchema = z.object({ limit:
z.coerce.number().optional() })) and then call validateQuery(coercingSchema)
with req.query { limit: '10' } (using the existing setup helper); assert next
was called and that req.query.limit === 10 (a number), so the test exercises
validateQuery's mutate-and-strip/coercion behavior rather than keeping the value
as a string.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/backend/src/middleware/validate.ts`:
- Around line 33-38: The delete-then-assign logic iterates keys on req.query and
uses "key in result.data", which will throw if result.data is a non-object;
update the cleanup to first guard that result.data is an object (e.g. check
typeof result.data === "object" && result.data !== null) before running the
Object.keys(req.query).forEach loop and Object.assign, or alternatively tighten
the schema/generic for validateQuery/validateParams to only accept object-shaped
outputs; locate the logic in validate.ts around req.query and result.data and
apply the guard or type constraint accordingly.

In `@packages/backend/tests/unit/middleware/validate.test.ts`:
- Around line 67-86: Add a new unit test that verifies coercion by defining a
schema that uses z.coerce.number() for limit (e.g., const coercingSchema =
z.object({ limit: z.coerce.number().optional() })) and then call
validateQuery(coercingSchema) with req.query { limit: '10' } (using the existing
setup helper); assert next was called and that req.query.limit === 10 (a
number), so the test exercises validateQuery's mutate-and-strip/coercion
behavior rather than keeping the value as a string.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 86818112-3206-4bb0-a2ee-a589a5667960

📥 Commits

Reviewing files that changed from the base of the PR and between db2e759 and 0c94aae.

📒 Files selected for processing (5)
  • packages/backend/src/middleware/validate.ts
  • packages/backend/src/schemas/management.ts
  • packages/backend/src/schemas/moderation.ts
  • packages/backend/tests/integration/services/redisCaching.test.ts
  • packages/backend/tests/unit/middleware/validate.test.ts
💤 Files with no reviewable changes (1)
  • packages/backend/tests/integration/services/redisCaching.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Quality Gates
  • GitHub Check: SonarCloud Scan
🔇 Additional comments (4)
packages/backend/src/schemas/management.ts (1)

72-74: LGTM — schema now correctly requires guildId alongside userId.

Matches the route pattern /api/guilds/:guildId/logs/users/:userId and keeps validation consistent with the new middleware stripping behavior.

packages/backend/src/middleware/validate.ts (1)

54-59: Same pattern as validateQuery — LGTM.

Duplicate of the query variant; see the note on line 33–38 regarding the in operator and non-object schema outputs. Not a blocker given all current call sites use z.object(...) schemas.

packages/backend/src/schemas/moderation.ts (1)

12-14: LGTM — aligns with route /api/guilds/:guildId/moderation/users/:userId/cases.

Validation now correctly covers both path params, and the handler already reads req.params.guildId and req.params.userId (see packages/backend/src/routes/moderation.ts:72-73), so no behavioral regression.

packages/backend/tests/unit/middleware/validate.test.ts (1)

123-141: LGTM — parallels the validateQuery assertions.

Tests correctly verify both assignment and unknown-field stripping for req.params.

@sonarqubecloud

Copy link
Copy Markdown

@LucasSantana-Dev
LucasSantana-Dev merged commit bcb13b0 into main Apr 17, 2026
12 checks passed
LucasSantana-Dev added a commit that referenced this pull request May 13, 2026
* test: add comprehensive validate middleware unit tests

* fix(tests): resolve 2 failing validate middleware tests and fix userCasesParam/userIdParam schemas

- Assign validated query/params to req.query/req.params to strip unknown fields
- Fix moderation.ts userCasesParam schema to include guildId
- Fix management.ts userIdParam schema to include guildId
- All 775 tests now pass

* test: fix validate middleware test assertions

* test: fix validate middleware test assertions

* fix: add type casts for Object.assign in validate middleware

* fix: use object cast instead of any in validate middleware
@LucasSantana-Dev
LucasSantana-Dev deleted the test/backend-validate-middleware branch May 23, 2026 02:21

This branch was successfully deployed

1 active deployment
Preview — f83f3660 Deployed Apr 17, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant