Skip to content

test: keep the unit suite off the network - #296

Merged
forcingfx merged 2 commits into
mainfrom
test/stub-real-network
Sep 9, 2026
Merged

forcingfx merged 2 commits into
mainfrom
test/stub-real-network

Conversation

@forcingfx

Copy link
Copy Markdown
Owner

What

Every npm test run printed ~30 lines of ECONNREFUSED / AbortError / AsyncTaskManager has been destroyed stack traces. All tests passed, so it went unnoticed.

Why

Two sources, attributed by temporarily wrapping node:http.request to name the running test:

  1. happy-dom is a real resource loader. <link rel="stylesheet"> and <iframe src> fixtures in sanitizer.test.js, feed-service.test.js and strategies.test.js made it open sockets to localhost:3000 and https://evil.com.
  2. billing-success.test.tsx rendered with a session_id, which fires the page's /api/license/retrieve fetch on mount, in three tests that never stubbed fetch.

Nothing awaited either, so the suite stayed green while doing real network I/O.

Fix

  • vitest.config.js: environmentOptions.happyDOM.settings disables CSS/JS file loading and iframe page loading.
  • billing-success.test.tsx: file-level pending fetch stub, plus an assertion that the page requests the session's license (the behaviour those tests were silently exercising).

A disabled iframe load still prints one NotSupportedError line per fixture (happy-dom's unconditional console.error, 4 lines total). Silencing those would need a fetch interceptor that changes semantics for every unstubbed page fetch; not worth it.

Prevention

  • tests/environment/no-real-network.test.ts spies node:http(s).request and asserts a stylesheet link and an iframe insert never reach it (red before the config change).
  • CLAUDE.md happy-dom gotchas record the setting and the fetch-stub rule.

Verification

before after
ECONNREFUSED lines 30 0
AbortError / AsyncTaskManager lines ~12 0
Tests 3963 3965 passed

npx tsc --noEmit: clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GQoLHbPfaTCHvPuaoqGZeJ

What: every 'npm test' run printed ~30 lines of ECONNREFUSED / AbortError /
AsyncTaskManager stack traces. All tests passed, so nobody looked.

Why: two sources. (1) happy-dom is a real resource loader: <link
rel="stylesheet"> and <iframe src> fixtures in sanitizer, feed-service and
discovery tests made it open sockets to localhost:3000 and https://evil.com.
(2) tests/pages/billing-success.test.tsx rendered with a session_id, which
fires the page's /api/license/retrieve fetch on mount, in three tests that
never stubbed fetch. Nothing awaited either, so the suite stayed green
while doing real network I/O — a direct violation of the no-network rule
for unit tests.

Fix: vitest.config.js disables CSS/JS file loading and iframe page loading
via environmentOptions.happyDOM.settings; billing-success gets a
file-level pending fetch stub plus an assertion that the page requests the
session's license. A disabled iframe load still prints one NotSupportedError
line per fixture (happy-dom's unconditional console.error) — four lines,
deterministic, documented.

Prevention: tests/environment/no-real-network.test.ts spies node:http(s)
request and asserts a stylesheet link and an iframe insert never reach it;
CLAUDE.md happy-dom gotchas record the setting and the fetch-stub rule.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQoLHbPfaTCHvPuaoqGZeJ
@vercel

vercel Bot commented Sep 9, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
feedzero Ready Ready Preview Sep 9, 2026 8:33pm UTC

Request Review

@forcingfx
forcingfx merged commit 80c58db into main Sep 9, 2026
17 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.

1 participant