Skip to content

test(sdk): make the x402Serve smoke test hermetic (#126) - #151

Open
fernando-mendoza wants to merge 1 commit into
nirium-protocol:mainfrom
fernando-mendoza:fix/126-hermetic-x402serve-smoke
Open

fernando-mendoza wants to merge 1 commit into
nirium-protocol:mainfrom
fernando-mendoza:fix/126-hermetic-x402serve-smoke

Conversation

@fernando-mendoza

Copy link
Copy Markdown
Collaborator

Makes the x402Serve smoke test hermetic. The test no longer calls the real facilitator, and a jest guard keeps that from coming back. This changes test files only; x402Serve() runtime defaults are unchanged.

What was leaking

In src/x402serve-smoke.test.ts, the guard-integration cases that get past the guard reach preflight(). That fetches https://channels.openzeppelin.com/x402/testnet/supported, which is one call in the replay test and two in the no-guard test. These are the 3 outbound requests per run from the 2 Oct harness. The tests passed either way because the assertions tolerated any downstream result.

How each "Done when" item is met

  • Zero outbound calls in the smoke test. The guard describe now stubs fetch with a 503 (jest.spyOn(globalThis, 'fetch'), restored after each test). The tests assert on the exact error path: the preflight URL, a 503 status, error: 'x402 payments unavailable', and detail: 'facilitator returned 503'. The results are deterministic, and the no-guard test is now a positive assertion rather than "not 409".
  • Guard in the jest setup. The new jest.no-network.js is wired as setupFilesAfterEnv. It refuses any non-loopback net.Socket#connect, which covers fetch/undici, http(s), tls and ws, and fails the test in afterEach. It fails the test even when the code under test swallows the error, as x402Serve does by turning it into a 503. Loopback stays allowed for local stub servers. Without the stub, it fails the two tests with outbound network blocked in tests: channels.openzeppelin.com:443.
  • npm test passes offline. I ran it inside a network namespace with no external interface (unshare -rn, loopback only).

Test results (Node 22.23.3, after npm run build)

  • npm test online: jest 3 suites, 56 passed; node:test 126 tests, 126 passed, 0 failed
  • npm test offline (unshare -rn): the same results
  • npx jest, 3 runs in a row: 56/56 each time
  • Guard probe (temporary test, not committed): a loopback HTTP server is allowed; an external fetch whose error is swallowed still fails the test
  • tsc --noEmit: OK; node scripts/clean-install-check.mjs: OK (jest.no-network.js is not in files, so it is not published)

Closes #126

The guard-integration cases reached preflight(), which fetched the default
facilitator (channels.openzeppelin.com) three times per run. Stub that fetch
with a 503 and assert on x402Serve's error path, so the result no longer
depends on a third-party service.

Add a jest setupFilesAfterEnv guard that refuses non-loopback sockets and
fails the test that opened one, even when the code under test swallows the
error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

x402serve smoke test: make it hermetic (no real facilitator calls)

1 participant