Skip to content

test: add unit tests for auth layer in apps/dashboard-api - #58

Merged
yash-pouranik merged 3 commits into
mainfrom
copilot/add-unit-tests-auth-layer
Mar 28, 2026
Merged

test: add unit tests for auth layer in apps/dashboard-api#58
yash-pouranik merged 3 commits into
mainfrom
copilot/add-unit-tests-auth-layer

Conversation

Copilot AI commented Mar 28, 2026

Copy link
Copy Markdown
Contributor
  • Explore repository and understand auth code
  • Fix authMiddleware.js to handle case-insensitive ****** (Bearer/bearer/BEARER)
  • Fix auth.controller.js — rename otpSchema references to Otp (was a ReferenceError bug)
  • Install Jest 30 and supertest 7 in apps/dashboard-api
  • Write unit tests for authMiddleware.js (Bearer/bearer/BEARER, missing/wrong header, invalid JWT)
  • Write unit tests for auth_limiter.js (rate limiting behaviour)
  • Write unit tests for auth.controller.js (login, register, refresh, logout, getMe, etc.)
  • Write unit tests for userAuth.controller.js (signup, login, me, verifyEmail, etc.)
  • Write unit tests for routes/auth.js (route wiring, middleware application)
  • Update CI workflow to run tests
  • Fix auth_limiter.test.js: wrap NODE_ENV mutations in try/finally to guarantee restore even on assertion failure
  • Fix auth.controller.test.js + userAuth.controller.test.js: replace z.email() with z.string().email() to match real schema conventions
  • Fix authMiddleware.test.js: correct inaccurate inline comment about 'Bearer ' split behaviour

📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.

@vercel

vercel Bot commented Mar 28, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
ur-backend-web-dashboard Ready Ready Preview, Comment Mar 28, 2026 10:54am

Copilot AI changed the title [WIP] Add unit tests for auth layer in apps/dashboard-api test: add unit tests for auth layer in apps/dashboard-api Mar 28, 2026
Copilot AI requested a review from yash-pouranik March 28, 2026 09:39
@yash-pouranik
yash-pouranik marked this pull request as ready for review March 28, 2026 09:59
Copilot AI review requested due to automatic review settings March 28, 2026 09:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds Jest-based unit test coverage for the apps/dashboard-api auth layer, along with a couple of small source fixes uncovered by exercising the code under test.

Changes:

  • Fix Authorization: Bearer ... parsing in authMiddleware to accept case-insensitive bearer schemes.
  • Fix OTP helper functions in auth.controller to use the correct Otp model identifier.
  • Introduce Jest + Supertest test suite for auth controllers/middleware/routes and wire tests into CI.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
apps/dashboard-api/src/middlewares/authMiddleware.js Makes Bearer scheme parsing case-insensitive and whitespace-tolerant.
apps/dashboard-api/src/controllers/auth.controller.js Fixes OTP helpers to reference Otp correctly.
apps/dashboard-api/src/tests/userAuth.controller.test.js Adds controller unit tests with heavy dependency mocks.
apps/dashboard-api/src/tests/routes.auth.test.js Adds route wiring tests for auth router (middleware/controller attachment).
apps/dashboard-api/src/tests/auth_limiter.test.js Adds unit tests for the auth rate limiter behavior across environments.
apps/dashboard-api/src/tests/authMiddleware.test.js Adds middleware tests covering cookies, Bearer casing, and JWT failure modes.
apps/dashboard-api/src/tests/auth.controller.test.js Adds unit tests for developer auth controller flows and error branches.
apps/dashboard-api/package.json Adds Jest/Supertest and a workspace test script + Jest config.
.github/workflows/ci.yml Adds a CI job to run dashboard-api tests with minimal permissions.

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

Comment thread apps/dashboard-api/src/__tests__/auth_limiter.test.js
Comment on lines +54 to +57
loginSchema: z.object({
email: z.email(),
password: z.string().min(1),
}),

Copilot AI Mar 28, 2026

Copy link

Choose a reason for hiding this comment

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

The mocked Zod schemas use z.email(), but the codebase’s real schemas use z.string().email(...) (see packages/common/src/utils/input.validation.js). Using z.email() is likely to throw at module-load time and/or diverge from real validation behavior. Update the mock schemas to use z.string().email() (and ideally mirror the real schema constraints).

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +56
email: z.email(),
password: z.string().min(1),
}),
signupSchema: z.object({
email: z.email(),
password: z.string().min(6),
}),
userSignupSchema: z.object({
email: z.email(),
password: z.string().min(6),
}).passthrough(),
resetPasswordSchema: z.object({
email: z.email(),
otp: z.string(),
newPassword: z.string().min(6),
}),
onlyEmailSchema: z.object({
email: z.email(),
}),
verifyOtpSchema: z.object({
email: z.email(),

Copilot AI Mar 28, 2026

Copy link

Choose a reason for hiding this comment

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

The @urbackend/common mock defines schemas with z.email(). Elsewhere in this repo (e.g. packages/common/src/utils/input.validation.js) schemas use z.string().email(...), and z.email() may not exist depending on Zod version. Please switch these mock schemas to z.string().email() (and keep them aligned with the real schema shapes/constraints) to avoid tests failing at import time or testing the wrong validation behavior.

Suggested change
email: z.email(),
password: z.string().min(1),
}),
signupSchema: z.object({
email: z.email(),
password: z.string().min(6),
}),
userSignupSchema: z.object({
email: z.email(),
password: z.string().min(6),
}).passthrough(),
resetPasswordSchema: z.object({
email: z.email(),
otp: z.string(),
newPassword: z.string().min(6),
}),
onlyEmailSchema: z.object({
email: z.email(),
}),
verifyOtpSchema: z.object({
email: z.email(),
email: z.string().email(),
password: z.string().min(1),
}),
signupSchema: z.object({
email: z.string().email(),
password: z.string().min(6),
}),
userSignupSchema: z.object({
email: z.string().email(),
password: z.string().min(6),
}).passthrough(),
resetPasswordSchema: z.object({
email: z.string().email(),
otp: z.string(),
newPassword: z.string().min(6),
}),
onlyEmailSchema: z.object({
email: z.string().email(),
}),
verifyOtpSchema: z.object({
email: z.string().email(),

Copilot uses AI. Check for mistakes.
Comment on lines +135 to +136
// The extra space splits into ['Bearer', '', ''] — no two-part match,
// so treated as missing token.

Copilot AI Mar 28, 2026

Copy link

Choose a reason for hiding this comment

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

This inline comment is inaccurate with the current implementation: authHeader.trim().split(/\s+/) would turn 'Bearer ' into ['Bearer'] (not ['Bearer', '', '']). Consider updating/removing the comment to match the actual behavior so future readers aren’t misled.

Suggested change
// The extra space splits into ['Bearer', '', ''] — no two-part match,
// so treated as missing token.
// After trimming and splitting on whitespace, only the scheme 'Bearer'
// remains and there is no token part, so it's treated as missing token.

Copilot uses AI. Check for mistakes.
@yash-pouranik

Copy link
Copy Markdown
Member

@copilot apply changes based on the comments in this thread

Agent-Logs-Url: https://github.com/yash-pouranik/urBackend/sessions/aad52c98-137b-432f-9a46-2b7218d2a5e6

Co-authored-by: yash-pouranik <172860064+yash-pouranik@users.noreply.github.com>
@yash-pouranik
yash-pouranik temporarily deployed to copilot/add-unit-tests-auth-layer - urBackend-frankfrut PR #58 March 28, 2026 10:54 — with Render Destroyed

Copilot AI commented Mar 28, 2026

Copy link
Copy Markdown
Contributor Author

@copilot apply changes based on the comments in this thread

Applied all four review points in commit d5fe8e0:

  • auth_limiter.test.js: All three tests that mutate process.env.NODE_ENV now wrap setup/assertions in try/finally to guarantee restoration even if an assertion throws.
  • auth.controller.test.js and userAuth.controller.test.js: All mock schema z.email() calls replaced with z.string().email() to match the real validation convention in packages/common/src/utils/input.validation.js.
  • authMiddleware.test.js: Corrected the inaccurate comment — 'Bearer '.trim().split(/\s+/) produces ['Bearer'] (single element, no token), so the updated comment now accurately describes the actual behaviour.

@yash-pouranik

Copy link
Copy Markdown
Member

@coderabbitai check if its mergeable and safe for prod?

@coderabbitai

coderabbitai Bot commented Mar 28, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get PR status, checks, and details
gh pr view 58 --repo yash-pouranik/urBackend --json state,mergeable,mergeStateStatus,statusCheckRollup,reviewDecision,reviews,isDraft,conflicts,baseRefName,headRefName,title,additions,deletions,changedFiles

echo "---CHECKS---"
gh pr checks 58 --repo yash-pouranik/urBackend

echo "---REVIEW COMMENTS---"
gh pr review-requests 58 --repo yash-pouranik/urBackend

echo "---COMMENTS---"
gh api repos/yash-pouranik/urBackend/pulls/58/comments --jq '[.[] | {path: .path, body: .body, line: .line, resolved: .resolved}]' 2>/dev/null | head -100

echo "---PR REVIEWS---"
gh api repos/yash-pouranik/urBackend/pulls/58/reviews --jq '[.[] | {user: .user.login, state: .state, body: .body}]'

echo "---OPEN ISSUES FROM REVIEW---"
gh api repos/yash-pouranik/urBackend/pulls/58/comments --jq '[.[] | select(.in_reply_to_id == null) | {path: .path, line: .original_line, body: .body[:200]}]'

Length of output: 7597


🏁 Script executed:

#!/bin/bash
# Get mergeable/merge state
gh pr view 58 --repo yash-pouranik/urBackend --json mergeable,mergeStateStatus,reviewDecision,isDraft,state

echo "---CHECK auth_limiter.test.js for try/finally---"
gh api repos/yash-pouranik/urBackend/contents/apps/dashboard-api/src/__tests__/auth_limiter.test.js \
  --jq '.content' | base64 -d 2>/dev/null | head -60

echo "---CHECK auth.controller.test.js for z.string().email---"
gh api repos/yash-pouranik/urBackend/contents/apps/dashboard-api/src/__tests__/auth.controller.test.js \
  --jq '.content' | base64 -d 2>/dev/null | grep -n "z\.email\|z\.string" | head -20

echo "---CHECK userAuth.controller.test.js for z.string().email---"
gh api repos/yash-pouranik/urBackend/contents/apps/dashboard-api/src/__tests__/userAuth.controller.test.js \
  --jq '.content' | base64 -d 2>/dev/null | grep -n "z\.email\|z\.string" | head -20

echo "---CHECK authMiddleware.test.js comment fix---"
gh api repos/yash-pouranik/urBackend/contents/apps/dashboard-api/src/__tests__/authMiddleware.test.js \
  --jq '.content' | base64 -d 2>/dev/null | grep -n -A2 -B2 "Bearer  \|trim\|split\|scheme\|token part\|missing token" | head -30

echo "---CI WORKFLOW---"
gh api repos/yash-pouranik/urBackend/contents/.github/workflows/ci.yml \
  --jq '.content' | base64 -d 2>/dev/null

echo "---RECENT CI RUNS---"
gh api repos/yash-pouranik/urBackend/actions/runs --jq '[.workflow_runs[:5] | .[] | {name: .name, status: .status, conclusion: .conclusion, head_sha: .head_sha, created_at: .created_at}]'

echo "---PR HEAD SHA---"
gh pr view 58 --repo yash-pouranik/urBackend --json headRefOid --jq '.headRefOid'

Length of output: 1898


🏁 Script executed:

#!/bin/bash
HEAD_SHA="d5fe8e029702969f921da7e7fed2e8f154c7f238"

echo "---CI RUN DETAILS for latest SHA---"
gh api repos/yash-pouranik/urBackend/actions/runs --jq \
  '[.workflow_runs[] | select(.head_sha == "d5fe8e029702969f921da7e7fed2e8f154c7f238") | {id: .id, name: .name, conclusion: .conclusion, status: .status}]'

echo "---GET CI RUN JOBS (CI Continuous Integration)---"
# Get the run IDs first
CI_RUN_ID=$(gh api repos/yash-pouranik/urBackend/actions/runs \
  --jq '[.workflow_runs[] | select(.head_sha == "d5fe8e029702969f921da7e7fed2e8f154c7f238" and .name == "CI (Continuous Integration)")] | .[0].id')
echo "CI Run ID: $CI_RUN_ID"
gh api repos/yash-pouranik/urBackend/actions/runs/$CI_RUN_ID/jobs \
  --jq '[.jobs[] | {name: .name, status: .status, conclusion: .conclusion, steps: [.steps[] | {name: .name, conclusion: .conclusion}]}]' 2>/dev/null

echo "---CodeQL Run Jobs---"
CODEQL_RUN_ID=$(gh api repos/yash-pouranik/urBackend/actions/runs \
  --jq '[.workflow_runs[] | select(.head_sha == "d5fe8e029702969f921da7e7fed2e8f154c7f238" and .name == "CodeQL Advanced")] | .[0].id')
echo "CodeQL Run ID: $CODEQL_RUN_ID"
gh api repos/yash-pouranik/urBackend/actions/runs/$CODEQL_RUN_ID/jobs \
  --jq '[.jobs[] | {name: .name, status: .status, conclusion: .conclusion}]' 2>/dev/null

echo "---CI WORKFLOW FROM PR BRANCH---"
gh api "repos/yash-pouranik/urBackend/contents/.github/workflows/ci.yml?ref=d5fe8e029702969f921da7e7fed2e8f154c7f238" \
  --jq '.content' | base64 -d 2>/dev/null

echo "---auth_limiter.test.js from PR branch---"
gh api "repos/yash-pouranik/urBackend/contents/apps/dashboard-api/src/__tests__/auth_limiter.test.js?ref=d5fe8e029702969f921da7e7fed2e8f154c7f238" \
  --jq '.content' | base64 -d 2>/dev/null | head -70

echo "---z.string().email check in auth.controller.test.js---"
gh api "repos/yash-pouranik/urBackend/contents/apps/dashboard-api/src/__tests__/auth.controller.test.js?ref=d5fe8e029702969f921da7e7fed2e8f154c7f238" \
  --jq '.content' | base64 -d 2>/dev/null | grep -n "z\.email\|z\.string" | head -20

echo "---z.string().email check in userAuth.controller.test.js---"
gh api "repos/yash-pouranik/urBackend/contents/apps/dashboard-api/src/__tests__/userAuth.controller.test.js?ref=d5fe8e029702969f921da7e7fed2e8f154c7f238" \
  --jq '.content' | base64 -d 2>/dev/null | grep -n "z\.email\|z\.string" | head -20

echo "---authMiddleware.test.js comment check---"
gh api "repos/yash-pouranik/urBackend/contents/apps/dashboard-api/src/__tests__/authMiddleware.test.js?ref=d5fe8e029702969f921da7e7fed2e8f154c7f238" \
  --jq '.content' | base64 -d 2>/dev/null | grep -n -B2 -A2 "Bearer  \|trim\|split\|scheme\|token part\|missing" | head -30

Length of output: 6190


@yash-pouranik Here's the full assessment:


✅ Code Quality — All 4 Review Issues Fixed

I verified the files on the PR branch (d5fe8e0). All issues flagged by Copilot have been addressed:

File Issue Status
auth_limiter.test.js NODE_ENV mutations wrapped in try/finally ✅ Fixed
auth.controller.test.js Schemas use z.string().email() (not z.email()) ✅ Fixed
userAuth.controller.test.js Schemas use z.string().email() (not z.email()) ✅ Fixed
authMiddleware.test.js Inaccurate inline comment corrected ✅ Fixed

⚠️ CI is NOT passing — Merge Blocked

The mergeStateStatus is UNSTABLE. Both workflows on the latest commit show conclusion: action_required and zero jobs were actually executed:

Workflow Conclusion Jobs Run
CI (Continuous Integration) action_required 0
CodeQL Advanced action_required 0

This means the workflows were triggered but never ran — they are sitting behind a GitHub Actions approval gate. The Jest tests added by this PR have not actually been verified in CI on the most recent commit.


🔴 Not Safe to Merge Yet

Before merging, you need to:

  1. Approve the pending GitHub Actions workflow runs — go to the Actions tab and approve the workflows for the latest commit (d5fe8e0).
  2. Wait for both CI (Continuous Integration) and CodeQL Advanced to complete successfully.
  3. Once both show green, the PR will be safe to merge.

The source fixes (case-insensitive Bearer parsing, Otp model rename) and the test suite look correct — the blocker is purely the unrun CI, not a code problem.

@yash-pouranik
yash-pouranik merged commit 03faef7 into main Mar 28, 2026
6 checks passed
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.

test: add unit tests for auth layer in apps/dashboard-api

3 participants