Skip to content

fix(server-elysia): update test mocks to match refactored http.createServer (#1204)#1210

Open
kagura-agent wants to merge 3 commits intoVoltAgent:mainfrom
kagura-agent:fix/elysia-server-provider-tests
Open

fix(server-elysia): update test mocks to match refactored http.createServer (#1204)#1210
kagura-agent wants to merge 3 commits intoVoltAgent:mainfrom
kagura-agent:fix/elysia-server-provider-tests

Conversation

@kagura-agent
Copy link
Copy Markdown

@kagura-agent kagura-agent commented Apr 17, 2026

Summary

Fixes #1204 — all 6 tests in elysia-server-provider.spec.ts were failing because the test mocks targeted the old app.listen() API, but startServer() was refactored to use http.createServer() + server.listen().

Changes

  • Added vi.mock('node:http') to mock createServer instead of relying on mockApp.listen
  • Updated beforeEach to configure mock server behavior (listen/close/once callbacks)
  • Added fetch to mock app (required by the HTTP request handler)
  • Updated assertions to verify createServer and server.listen calls
  • Updated stop test to verify server.close() is called
  • Updated error test to simulate errors via server.once('error') handler

Testing

All 6 tests pass:

✓ should start the server
✓ should stop the server
✓ should throw if already running
✓ should configure websocket if enabled
✓ should extract and display custom endpoints from configureApp
✓ should handle startup errors and release port

Test Files  1 passed (1)
Tests       6 passed (6)

Closes #1204


Summary by cubic

Updates Elysia server tests to mock node:http (createServer/server.listen) after the startServer refactor, restoring all six cases (fixes #1204). Also secures the dev auth bypass in @voltagent/server-core by requiring NODE_ENV=development or test only (fail-closed), and applies the same check to WebSocket paths.

  • Bug Fixes
    • @voltagent/server-elysia: mock node:http; assert createServer, server.listen, and server.close; simulate startup errors via server.once('error').
    • @voltagent/server-core: add isDevEnvironment(); update isDevRequest() and WS dev bypass to use it; treat empty/undefined NODE_ENV as production; add unit tests.

Written for commit e639394. Summary will update on new commits.

Summary by CodeRabbit

  • Bug Fixes

    • Hardened development authentication bypass security by ensuring it only activates in explicitly configured development and test environments rather than any non-production setting, preventing unintended bypass in misconfigured deployments.
  • Tests

    • Updated and expanded test coverage for authentication bypass behavior, environment detection, and WebSocket server initialization across services.

…oltAgent#1206)

Previously isDevRequest() treated any non-production NODE_ENV (including
undefined) as a development environment, allowing auth bypass with a simple
header. Deployed servers that forgot NODE_ENV=production were fully open.

Now only NODE_ENV=development or NODE_ENV=test enable the dev bypass
(fail-closed). Undefined/empty NODE_ENV is treated as production.
…ment helper

Address CodeRabbit review: WebSocket auth functions in setup.ts also used
the vulnerable NODE_ENV !== 'production' check. Extract isDevEnvironment()
as a shared helper used by both HTTP and WebSocket auth paths.

Also fix test names (empty vs undefined) and add isDevEnvironment unit tests.
…Server (VoltAgent#1204)

Tests were mocking the old app.listen() API, but startServer() was refactored
to use Node.js http.createServer() + server.listen(). Updated mocks to target
node:http module instead, restoring test coverage for all 6 test cases.
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 17, 2026

🦋 Changeset detected

Latest commit: e639394

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@voltagent/server-core Patch
@voltagent/server-elysia Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 17, 2026

📝 Walkthrough

Walkthrough

This PR refactors authentication environment gating and updates Elysia server provider tests. It introduces a centralized isDevEnvironment() function that enables dev bypass only when NODE_ENV is explicitly "development" or "test", applying fail-closed behavior (undefined or empty treated as production). Auth checks and WebSocket setup are updated to use this function. Additionally, Elysia provider tests are patched to mock node:http.createServer instead of the deprecated app.listen API, aligning test expectations with the refactored implementation.

Changes

Cohort / File(s) Summary
Changesets
.changeset/fix-dev-auth-bypass-node-env.md, .changeset/fix-elysia-server-provider-tests.md
Documentation of patch releases for @voltagent/server-core and @voltagent/server-elysia tracking dev auth bypass tightening and test mock alignment.
Auth Environment Gating
packages/server-core/src/auth/utils.ts, packages/server-core/src/auth/utils.spec.ts
Introduced new isDevEnvironment() export that returns true only for explicit "development" or "test" NODE_ENV values (fail-closed). Updated isDevRequest() to use this function instead of checking NODE_ENV !== "production", tightening dev bypass requirements. Expanded test coverage for empty/undefined NODE_ENV cases.
WebSocket Setup
packages/server-core/src/websocket/setup.ts
Updated dev bypass detection in both header and query-param paths to use centralized isDevEnvironment() instead of direct NODE_ENV checks.
Elysia Provider Tests
packages/server-elysia/src/elysia-server-provider.spec.ts
Added mock for node:http module with createServer, listen, close, and once behaviors. Refactored test assertions to validate http.createServer invocation and mockServer.listen() calls instead of outdated app.listen expectations. Updated error simulation to capture and invoke listener callbacks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • omeraplak

Poem

🐰 Thumper's Dev Environment Ballad

Auth gates now closed when NODE_ENV's unsure,
Dev bypass locked 'til "dev" or "test" appear,
No secret headers bypass code so pure,
WebSockets aligned with centered logic clear,
And Elysia's mocks dance true with Node's HTTP sphere! 🎭

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes out-of-scope security changes to the auth bypass logic in server-core that are unrelated to the stated issue #1204 about Elysia server provider tests. Move auth-related changes (isDevEnvironment, NODE_ENV fail-closed, websocket auth) to a separate PR focused on fixing the dev auth bypass vulnerability.
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: updating test mocks to match a refactored http.createServer implementation in server-elysia.
Description check ✅ Passed The description provides comprehensive details about the bug fix, specific changes made, test results, and linked issue, closely following the template structure.
Linked Issues check ✅ Passed All code changes directly address the requirements of issue #1204: mocking node:http.createServer, updating assertions for createServer/server.listen/server.close, and simulating startup errors via server.once.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Contributor

@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 (5)
packages/server-elysia/src/elysia-server-provider.spec.ts (2)

22-32: Module-level mockServer is shared across tests.

Since mockServer is defined at module scope and vi.clearAllMocks() only resets call history (not implementations or properties), state like listening: true persists across tests. The current beforeEach re-applies implementations for listen/close/once, which is sufficient for the present test set, but any future test that mutates mockServer.listening (or adds new methods) will leak into other tests. Consider resetting mockServer properties explicitly in beforeEach to make the isolation boundary obvious.

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

In `@packages/server-elysia/src/elysia-server-provider.spec.ts` around lines 22 -
32, The module-level mockServer object is shared across tests causing state
leakage; in the beforeEach where you reapply implementations for
listen/close/once, also explicitly reset mockServer properties (e.g., set
mockServer.listening = false or true as appropriate and reinitialize any added
methods) so each test starts with a fresh known state; update the beforeEach to
reassign mockServer.listening and any other mutable fields on the mockServer
used by tests (while keeping vi.mock("node:http") and the mocked
listen/close/once implementations intact).

139-160: Startup error simulation relies on registration order — worth a brief comment.

The test works because the implementation calls server.once("error", reject) before server.listen(...) (see elysia-server-provider.ts:87-91), so errorHandler is captured before mockServer.listen synchronously invokes it. If the implementation ever reorders these calls, errorHandler would be undefined and the test would silently hang on an unresolved promise rather than fail loudly. A short inline comment noting this ordering dependency, or a defensive expect(errorHandler).toBeDefined() before triggering it, would make the failure mode more diagnosable.

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

In `@packages/server-elysia/src/elysia-server-provider.spec.ts` around lines 139 -
160, The test relies on server.once("error", ...) being called before
server.listen(...) so errorHandler is set; add a defensive check (or short
inline comment) in the test to make this dependency explicit and fail loudly if
ordering changes: after mockServer.once.mockImplementation and before invoking
mockServer.listen (or before calling provider.start()), assert that errorHandler
is defined (e.g., expect(errorHandler).toBeDefined()) and/or add a brief comment
referencing the ordering dependency; this targets the errorHandler captured in
the it("should handle startup errors and release port") block and ensures the
test won't hang silently if server.once is registered after listen.
packages/server-core/src/auth/utils.spec.ts (1)

9-29: Consider adding an explicit undefined NODE_ENV case.

The suite covers "development", "test", "production", and "", but the docstring on isDevEnvironment() emphasizes that undefined NODE_ENV is the primary fail-closed scenario (deployments that forgot to set it). vi.stubEnv("NODE_ENV", undefined) (or deleting via delete process.env.NODE_ENV inside the test) would pin down that behavior explicitly.

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

In `@packages/server-core/src/auth/utils.spec.ts` around lines 9 - 29, Add an
explicit test to assert that isDevEnvironment() returns false when NODE_ENV is
undefined: inside the existing "isDevEnvironment" describe block add a case that
clears or unsets the env (e.g., use vi.stubEnv("NODE_ENV", undefined) or delete
process.env.NODE_ENV) and expect(isDevEnvironment()).toBe(false); this pins down
the fail-closed behavior for undefined NODE_ENV and uses the same test helpers
(vi.stubEnv) already present in the suite.
.changeset/fix-dev-auth-bypass-node-env.md (1)

5-12: Consider mentioning test in the headline for completeness.

The title says "require explicit NODE_ENV=development" but the body (and implementation) also accepts NODE_ENV=test. A small wording tweak would prevent confusion for consumers scanning the changelog.

📝 Proposed wording
-fix(auth): require explicit NODE_ENV=development for dev auth bypass
+fix(auth): require explicit NODE_ENV=development|test for dev auth bypass
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.changeset/fix-dev-auth-bypass-node-env.md around lines 5 - 12, Update the
changelog headline to mention both development and test environments so it
matches the implementation: change the title in
.changeset/fix-dev-auth-bypass-node-env.md from "require explicit
NODE_ENV=development for dev auth bypass" to something like "require explicit
NODE_ENV=development or NODE_ENV=test for dev auth bypass" and ensure any
summary lines referencing isDevRequest() or the dev bypass behavior also mention
"test" to avoid consumer confusion.
packages/server-core/src/auth/utils.ts (1)

45-58: Consider aligning shouldEnableSwaggerUI with the new helper.

packages/server-core/src/server/app-setup.ts still uses a direct process.env.NODE_ENV === "production" check with fail-open semantics (any non-production value enables Swagger UI). It's not strictly a security issue since Swagger exposure is less sensitive than auth bypass, but for consistency — and to avoid the same "undefined NODE_ENV on deployed server" footgun — consider switching it to !isDevEnvironment()-style gating, or at minimum a shared constant, so env checks across the package stay uniform.

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

In `@packages/server-core/src/auth/utils.ts` around lines 45 - 58, The server
app-setup uses a direct process.env.NODE_ENV === "production" check for
shouldEnableSwaggerUI which is inconsistent with the new
isDevEnvironment()/isDevRequest() helper pattern; update shouldEnableSwaggerUI
in packages/server-core/src/server/app-setup.ts to use the shared
isDevEnvironment() (or the inverse !isDevEnvironment()) instead of comparing
NODE_ENV directly so that Swagger gating follows the same environment logic as
isDevRequest(); ensure you import isDevEnvironment from auth/utils and replace
the existing production-check branch with a call to isDevEnvironment() (or a
shared constant) to maintain uniform behavior across the package.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.changeset/fix-dev-auth-bypass-node-env.md:
- Around line 5-12: Update the changelog headline to mention both development
and test environments so it matches the implementation: change the title in
.changeset/fix-dev-auth-bypass-node-env.md from "require explicit
NODE_ENV=development for dev auth bypass" to something like "require explicit
NODE_ENV=development or NODE_ENV=test for dev auth bypass" and ensure any
summary lines referencing isDevRequest() or the dev bypass behavior also mention
"test" to avoid consumer confusion.

In `@packages/server-core/src/auth/utils.spec.ts`:
- Around line 9-29: Add an explicit test to assert that isDevEnvironment()
returns false when NODE_ENV is undefined: inside the existing "isDevEnvironment"
describe block add a case that clears or unsets the env (e.g., use
vi.stubEnv("NODE_ENV", undefined) or delete process.env.NODE_ENV) and
expect(isDevEnvironment()).toBe(false); this pins down the fail-closed behavior
for undefined NODE_ENV and uses the same test helpers (vi.stubEnv) already
present in the suite.

In `@packages/server-core/src/auth/utils.ts`:
- Around line 45-58: The server app-setup uses a direct process.env.NODE_ENV ===
"production" check for shouldEnableSwaggerUI which is inconsistent with the new
isDevEnvironment()/isDevRequest() helper pattern; update shouldEnableSwaggerUI
in packages/server-core/src/server/app-setup.ts to use the shared
isDevEnvironment() (or the inverse !isDevEnvironment()) instead of comparing
NODE_ENV directly so that Swagger gating follows the same environment logic as
isDevRequest(); ensure you import isDevEnvironment from auth/utils and replace
the existing production-check branch with a call to isDevEnvironment() (or a
shared constant) to maintain uniform behavior across the package.

In `@packages/server-elysia/src/elysia-server-provider.spec.ts`:
- Around line 22-32: The module-level mockServer object is shared across tests
causing state leakage; in the beforeEach where you reapply implementations for
listen/close/once, also explicitly reset mockServer properties (e.g., set
mockServer.listening = false or true as appropriate and reinitialize any added
methods) so each test starts with a fresh known state; update the beforeEach to
reassign mockServer.listening and any other mutable fields on the mockServer
used by tests (while keeping vi.mock("node:http") and the mocked
listen/close/once implementations intact).
- Around line 139-160: The test relies on server.once("error", ...) being called
before server.listen(...) so errorHandler is set; add a defensive check (or
short inline comment) in the test to make this dependency explicit and fail
loudly if ordering changes: after mockServer.once.mockImplementation and before
invoking mockServer.listen (or before calling provider.start()), assert that
errorHandler is defined (e.g., expect(errorHandler).toBeDefined()) and/or add a
brief comment referencing the ordering dependency; this targets the errorHandler
captured in the it("should handle startup errors and release port") block and
ensures the test won't hang silently if server.once is registered after listen.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fcbab152-366c-47a8-97b9-9b525ba07170

📥 Commits

Reviewing files that changed from the base of the PR and between 71c9f84 and e639394.

📒 Files selected for processing (6)
  • .changeset/fix-dev-auth-bypass-node-env.md
  • .changeset/fix-elysia-server-provider-tests.md
  • packages/server-core/src/auth/utils.spec.ts
  • packages/server-core/src/auth/utils.ts
  • packages/server-core/src/websocket/setup.ts
  • packages/server-elysia/src/elysia-server-provider.spec.ts

Copy link
Copy Markdown
Contributor

@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 6 files

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.

[BUG] Elysia server provider test suite entirely broken — stale mocks after Node.js HTTP refactor

1 participant