Skip to content

test(auth): add unit tests for auth.service and fix passport local strategy done() call#3175

Merged
PierreBrisorgueil merged 4 commits intomasterfrom
test/auth-service-unit-tests
Mar 2, 2026
Merged

test(auth): add unit tests for auth.service and fix passport local strategy done() call#3175
PierreBrisorgueil merged 4 commits intomasterfrom
test/auth-service-unit-tests

Conversation

@PierreBrisorgueil
Copy link
Contributor

@PierreBrisorgueil PierreBrisorgueil commented Mar 2, 2026

Summary

  • What changed: Added 17 unit tests for auth.service.js covering all six exported functions; fixed a bug in the passport local strategy error handler
  • Why: auth.service.js had zero unit tests; the local strategy was calling done() with no arguments on authentication failure, which causes passport to treat the failure as an internal error rather than an unauthorized response
  • Related issues: Closes test(auth): add unit tests for auth.service and fix passport local strategy done() call #3174

Scope

  • Module(s) impacted: modules/auth (service unit tests, local strategy)
  • Cross-module impact: none
  • Risk level: low

Validation

  • npm run lint
  • npm test (unit tests — 101 passing)
  • Manual checks done (if applicable)

Guardrails check

  • No secrets or credentials introduced (.env*, secrets/**, keys, tokens)
  • No risky rename/move of core stack paths
  • Changes remain merge-friendly for downstream projects
  • Tests added or updated when behavior changed

Notes for reviewers

  • Security considerations: The done()done(null, false, { message }) fix ensures passport correctly returns a 401 (Unauthorized) rather than a 500 (Internal Server Error) when credentials are invalid — a security-relevant correction
  • Mergeability considerations: New test file is purely additive; the one-line local.js fix is self-contained
  • Follow-up tasks: none

Summary by CodeRabbit

  • Bug Fixes

    • Improved local authentication error handling so service-level errors are treated as invalid credentials while other errors propagate normally.
  • Tests

    • Added comprehensive unit tests for the authentication service covering password hashing/comparison, credential verification, password strength checks, random passphrase generation, and input sanitization.

…rategy done() call

- Add auth.service.unit.tests.js: 17 unit tests covering all six service functions
  (removeSensitive, comparePassword, hashPassword, authenticate, checkPassword,
  generateRandomPassphrase) using jest.unstable_mockModule for ESM compatibility
- Fix local strategy error handler: done() → done(null, false, { message }) so
  passport correctly signals authentication failure instead of internal error

Closes #3174
@PierreBrisorgueil PierreBrisorgueil added Fix A bug fix Tests Adding missing tests or correcting existing labels Mar 2, 2026
@PierreBrisorgueil PierreBrisorgueil self-assigned this Mar 2, 2026
@PierreBrisorgueil PierreBrisorgueil added Fix A bug fix Tests Adding missing tests or correcting existing labels Mar 2, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 2, 2026

Warning

Rate limit exceeded

@PierreBrisorgueil has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 17 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 9e457cc and f78367b.

📒 Files selected for processing (1)
  • modules/auth/tests/auth.integration.tests.js
📝 Walkthrough

Walkthrough

Fixes passport local strategy error handling to return authentication-failure via done(null, false, { message }) and adds a comprehensive Jest unit test suite for the authentication service covering six functions and multiple edge cases.

Changes

Cohort / File(s) Summary
Local Strategy Error Handling
modules/auth/config/strategies/local.js
Imports AppError and updates the strategy catch block to treat service-level errors as invalid credentials (done(null, false, { message: 'Invalid email or password' })) while rethrowing other unexpected errors via done(err).
Auth Service Unit Tests
modules/auth/tests/auth.unit.tests.js
Adds a new Jest ES module test suite for AuthService with mocks for repositories and libs; covers removeSensitive, comparePassword, hashPassword, authenticate, checkPassword, and generateRandomPassphrase, including edge cases and input coercion checks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I hopped through code at break of day,
I caught the bug and showed the way,
Tests now hum and logins say,
"Done(null, false)" — hip hooray! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the two main changes: adding unit tests for auth.service and fixing the passport local strategy done() call, which directly aligns with the changeset.
Description check ✅ Passed The description comprehensively follows the template with all required sections completed: summary, scope, validation, guardrails checks, and notes for reviewers.
Linked Issues check ✅ Passed All objectives from issue #3174 are met: 17 unit tests added covering all six auth.service functions with proper mocking, and the local strategy error handling is fixed to use done(null, false, { message }).
Out of Scope Changes check ✅ Passed Changes are scoped to modules/auth with two focused modifications: new unit test file and local strategy error handling fix, both directly supporting the issue objectives.
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 unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch test/auth-service-unit-tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@PierreBrisorgueil PierreBrisorgueil marked this pull request as ready for review March 2, 2026 07:35
Copilot AI review requested due to automatic review settings March 2, 2026 07:35
@codecov
Copy link

codecov bot commented Mar 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.87%. Comparing base (8b02ceb) to head (f78367b).
⚠️ Report is 4 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3175      +/-   ##
==========================================
+ Coverage   89.86%   89.87%   +0.01%     
==========================================
  Files          52       52              
  Lines        1164     1166       +2     
  Branches      234      235       +1     
==========================================
+ Hits         1046     1048       +2     
  Misses        107      107              
  Partials       11       11              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

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 unit-level test coverage for modules/auth/services/auth.service.js and adjusts the Passport local strategy failure path so invalid credentials are reported as an authentication failure rather than an internal error.

Changes:

  • Added a new unit test suite covering removeSensitive, comparePassword, hashPassword, authenticate, checkPassword, and generateRandomPassphrase.
  • Updated the Passport local strategy to call done(null, false, { message }) on errors instead of calling done() with no args.

Reviewed changes

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

File Description
modules/auth/tests/auth.service.unit.tests.js New unit tests for all exported AuthService functions (with module mocks for repo, bcrypt, zxcvbn, and config).
modules/auth/config/strategies/local.js Adjusts error handling to return an auth failure via done(null, false, info) instead of an empty done() call.

Copy link

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
modules/auth/config/strategies/local.js (1)

16-27: ⚠️ Potential issue | 🟡 Minor

Add JSDoc to the modified strategy verifier function.

The async verifier callback was modified but has no JSDoc header (@param/@returns).

As per coding guidelines, **/*.js: Every new or modified function must have a JSDoc header: one-line description, @param for each argument, @returns for any non-void return value (always include @returns for async functions to document the resolved value).

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

In `@modules/auth/config/strategies/local.js` around lines 16 - 27, Add a JSDoc
header above the async verifier callback (the async (email, password, done) => {
... } function) describing its purpose in one line, add `@param` tags for email
(string), password (string) and done (Passport-style callback) and add an
`@returns` tag documenting the Promise resolution (e.g., Promise<void> or the
resolved value from calling done). Keep the JSDoc concise and placed immediately
above the anonymous verifier function inside the strategy so it satisfies the
/** ... */ rule for modified JS functions.
🧹 Nitpick comments (1)
modules/auth/config/strategies/local.js (1)

24-26: Distinguish authentication failures from infrastructure errors in the catch block.

The current implementation converts all exceptions—including database and bcrypt errors—into auth failures. Since authenticate() throws both AppError('invalid user or password.') for expected auth failures and can propagate infrastructure errors (from UserRepository.get() and bcrypt.compare()), use done(err) for non-authentication exceptions to surface real operational issues instead of masking them as invalid credentials.

Suggested improvement
-        } catch (_err) {
-          return done(null, false, { message: 'Invalid email or password' });
+        } catch (err) {
+          if (err?.message === 'invalid user or password.') {
+            return done(null, false, { message: 'Invalid email or password' });
+          }
+          return done(err);
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@modules/auth/config/strategies/local.js` around lines 24 - 26, The catch
block currently converts every exception into an authentication failure; update
it to rethrow/invoke done(err) for infrastructure errors while preserving the
auth-failure path for expected auth errors: detect whether the caught error is
the expected authentication sentinel (e.g., an instance of AppError or has the
message 'invalid user or password.' produced by
authenticate()/UserRepository.get()/bcrypt.compare()), and if so call done(null,
false, { message: 'Invalid email or password' }); otherwise call done(err) to
surface real operational errors from UserRepository.get, bcrypt.compare, or
other unexpected exceptions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@modules/auth/tests/auth.service.unit.tests.js`:
- Around line 10-180: Add JSDoc headers to every new/modified function in this
test module (including the callbacks passed to describe, test, and beforeEach
and any standalone helper functions) so the repository JSDoc rule is satisfied;
for each function (e.g., the beforeEach callback, describe callbacks like 'Auth
service unit tests:' and nested describe blocks, and each test callback such as
the async tests in comparePassword, hashPassword, authenticate), add a one-line
description, `@param` entries for any parameters, and `@returns` for any non-void or
async functions (document the resolved value for async tests). Ensure each JSDoc
immediately precedes the function expression/arrow function so linters pick it
up.

---

Outside diff comments:
In `@modules/auth/config/strategies/local.js`:
- Around line 16-27: Add a JSDoc header above the async verifier callback (the
async (email, password, done) => { ... } function) describing its purpose in one
line, add `@param` tags for email (string), password (string) and done
(Passport-style callback) and add an `@returns` tag documenting the Promise
resolution (e.g., Promise<void> or the resolved value from calling done). Keep
the JSDoc concise and placed immediately above the anonymous verifier function
inside the strategy so it satisfies the /** ... */ rule for modified JS
functions.

---

Nitpick comments:
In `@modules/auth/config/strategies/local.js`:
- Around line 24-26: The catch block currently converts every exception into an
authentication failure; update it to rethrow/invoke done(err) for infrastructure
errors while preserving the auth-failure path for expected auth errors: detect
whether the caught error is the expected authentication sentinel (e.g., an
instance of AppError or has the message 'invalid user or password.' produced by
authenticate()/UserRepository.get()/bcrypt.compare()), and if so call done(null,
false, { message: 'Invalid email or password' }); otherwise call done(err) to
surface real operational errors from UserRepository.get, bcrypt.compare, or
other unexpected exceptions.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c9b2d83 and f021729.

📒 Files selected for processing (2)
  • modules/auth/config/strategies/local.js
  • modules/auth/tests/auth.service.unit.tests.js

- Rename auth.service.unit.tests.js → auth.unit.tests.js to match project naming convention
- Fix local strategy catch block: propagate unexpected errors via done(err) instead of
  silently converting all exceptions (including DB/bcrypt failures) to authentication failures
Copy link

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
modules/auth/config/strategies/local.js (1)

10-17: ⚠️ Potential issue | 🟡 Minor

Add JSDoc headers for modified functions.

The modified strategy initializer/verify function does not have JSDoc headers. This repo rule applies to modified JS functions too.

As per coding guidelines, **/*.{js,ts}: Every new or modified function must have a JSDoc header: one-line description, @param for each argument, and @returns for non-void/async functions.

Also applies to: 25-31

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

In `@modules/auth/config/strategies/local.js` around lines 10 - 17, Add JSDoc
headers to the exported strategy initializer (export default () => { ... }) and
the async verify callback passed to new Strategy (async (email, password, done)
=> { ... }); for each include a one-line description and `@param` entries for each
argument (e.g., email, password, done) and for the async verify include an
`@returns` {Promise<void>} (or appropriate return type) tag. Ensure the JSDoc
appears immediately above the export default function and immediately above the
verify function definition (the anonymous async verify passed into new Strategy)
and also apply the same JSDoc pattern to the other modified function blocks
referenced in the review.
♻️ Duplicate comments (1)
modules/auth/tests/auth.unit.tests.js (1)

10-180: ⚠️ Potential issue | 🟡 Minor

JSDoc rule is still unmet across new test callbacks.

Callbacks added in this file (mock module factories, beforeEach, describe, and test handlers) are new/modified functions and still missing JSDoc blocks.

As per coding guidelines, **/*.js: Every new or modified function must have a JSDoc header: one-line description, @param for each argument, and @returns for non-void/async functions.

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

In `@modules/auth/tests/auth.unit.tests.js` around lines 10 - 180, The file is
missing JSDoc headers for newly added/modified callbacks: the mock factory
functions passed to jest.unstable_mockModule, the beforeEach callback, and each
describe/test handler (all arrow functions used in describe(...) and test(...)).
Add a JSDoc block above each callback with a one-line description, `@param`
entries for each argument (e.g., evt or done if used) and `@returns` for any
non-void or async handlers (e.g., tests/blocks returning Promises), covering the
mock factories, beforeEach, and all test callbacks like those around
removeSensitive, comparePassword, hashPassword, authenticate, checkPassword, and
generateRandomPassphrase.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@modules/auth/config/strategies/local.js`:
- Line 7: The import for AppError in modules/auth/config/strategies/local.js is
pointing to the wrong relative path; locate the real AppError module in the repo
and update the import statement that currently references
'../../../lib/helpers/AppError.js' to the correct relative path (or use the
project alias/import root if configured) so the AppError symbol resolves; ensure
the import still uses the exact exported name AppError and run the tests/CI to
confirm resolution.

---

Outside diff comments:
In `@modules/auth/config/strategies/local.js`:
- Around line 10-17: Add JSDoc headers to the exported strategy initializer
(export default () => { ... }) and the async verify callback passed to new
Strategy (async (email, password, done) => { ... }); for each include a one-line
description and `@param` entries for each argument (e.g., email, password, done)
and for the async verify include an `@returns` {Promise<void>} (or appropriate
return type) tag. Ensure the JSDoc appears immediately above the export default
function and immediately above the verify function definition (the anonymous
async verify passed into new Strategy) and also apply the same JSDoc pattern to
the other modified function blocks referenced in the review.

---

Duplicate comments:
In `@modules/auth/tests/auth.unit.tests.js`:
- Around line 10-180: The file is missing JSDoc headers for newly added/modified
callbacks: the mock factory functions passed to jest.unstable_mockModule, the
beforeEach callback, and each describe/test handler (all arrow functions used in
describe(...) and test(...)). Add a JSDoc block above each callback with a
one-line description, `@param` entries for each argument (e.g., evt or done if
used) and `@returns` for any non-void or async handlers (e.g., tests/blocks
returning Promises), covering the mock factories, beforeEach, and all test
callbacks like those around removeSensitive, comparePassword, hashPassword,
authenticate, checkPassword, and generateRandomPassphrase.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f021729 and 257cf7c.

📒 Files selected for processing (2)
  • modules/auth/config/strategies/local.js
  • modules/auth/tests/auth.unit.tests.js

Adds an integration test that mocks AuthService.authenticate to throw a plain
Error (non-AppError) and verifies the server responds with 500, covering the
done(err) branch in the local passport strategy.
@PierreBrisorgueil PierreBrisorgueil merged commit a44e2eb into master Mar 2, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Fix A bug fix Tests Adding missing tests or correcting existing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test(auth): add unit tests for auth.service and fix passport local strategy done() call

2 participants