test(web): pin four unprotected server-function surfaces - #3177
Conversation
Four areas had no coverage in the tree. Each of the 33 tests here was proven to detect a regression by mutating the built runtime and watching it go red; three candidate assertions were dropped for passing both before and after. - rich arguments: File/Blob/typed-array/FormData/URLSearchParams round trip, and the bound `?args=` + trailing-body ordering. `?args=` ordering had no test at all, and a `push`->`unshift` mutation showed why. - wrapInvocation: both legs, deny-gate, sync transparency, invocation identity. The direct SSR leg could previously skip the configured policy with nothing noticing. - outcome digest: `foldedHeaders`, `targetUrl` and `revalidateKeys` had zero references anywhere in the test tree, plus `foldSetCookies`. - createNoJSHandler: destination choice and flash behaviour. Suite: 524 -> 557 passing, no existing test touched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VqfkrUXVM5zzVa2aNNFXXa
|
Merging this PR will degrade performance by 14.29%
|
| Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|
| ❌ | merge |
70.9 µs | 138.2 µs | -48.71% |
| ⚡ | merge |
322.7 µs | 225.3 µs | +43.24% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing frenzzy:test/server-function-coverage (83ea886) with next (f051db6)
Footnotes
-
132 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
Review against the surrounding specs turned up four things a maintainer
would have caught, so they are fixed here rather than argued about.
- rename rich-arguments -> body-formats. `enableRichArguments` is a real
opt-in codec (server-functions/src/rich-args.ts) that this file explicitly
disclaims and that still has no coverage anywhere; the old name sent
anyone grepping for it to the one file that does not test it. The source
calls what this file pins `BodyFormat`.
- name the wire formats. The header was spelled three different ways across
the four files and disagreed with request-bounds and shared.ts; bare
integers ("5", "4", "7", "2", "3") are now FILE_FORMAT and friends, and
ERROR_HEADER / GENERIC_SERVER_ERROR_MESSAGE / FLASH_COOKIE are imported
rather than spelled.
- strengthen three assertions. `not.toContain(secret)` alone is the exact
anti-pattern failure-sanitization documents as having let a broken fix go
green, so it is now paired with the positive; a substring match on an
encoded body became `decodeResponse`; and `toEqual` with an `undefined`
key asserted nothing, so it is `toStrictEqual`.
- delete ~30 lines of inert setup, each verified by removal: a hand-rolled
createEvent in the transport helper, five unused createEvent options, and
a whole AsyncLocalStorage install in a file that never enters the handler.
Also: the no-JS fixture posted to /_server/data/<id> without a form content
type — a browser form posts to fn.url, the bare address (solidjs#3094) — and the
four docblocks now say plainly that they pin previously-uncovered surface,
since every existing spec in this directory cites an issue and their silence
read as an omission.
Suite unchanged at 52 files / 557 passed / 2 skipped.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VqfkrUXVM5zzVa2aNNFXXa
Four areas of the server-function surface had no coverage in the tree. This adds 33 tests across four files, in the existing idiom, touching no existing test and no runtime code.
What is pinned, and why each earned a place
server-functions-rich-arguments.spec.tsx?args=+ trailing-body ordering — which had no test at allserver-functions-invocation-wrap.spec.tsxwrapInvocationon both legs, deny-gate, sync transparency, invocation identity. The direct SSR leg could skip the configured policy with nothing noticingserver-functions-outcome-digest.spec.tsxfoldedHeaders,targetUrlandrevalidateKeyshad zero references anywhere in the test tree, plusfoldSetCookiesserver-functions-nojs-destination.spec.tsxcreateNoJSHandlerdestination choice and flash behaviourEvery test is mutation-proven
A test that passes both before and after a regression is worthless, so each one here was checked by mutating the built runtime and confirming it goes red, then reverting. Representative:
formData.get(FILE_FORM_KEY)→get("file")— both File tests rednew Uint8Array(body)→body.buffer— typed-array view test red (ships 8 bytes instead of 3)parsed.push(decoded)→unshift— both?args=ordering tests redconfig.wrapInvocation— "a render cannot walk around the policy" redsanitizeServerError→ passthrough — a secret leaks into the body, redtargetUrlguard removed — off-site redirect test rednew Headers(headers)→headers— three tests red (input mutation)validRedirectStatuses.has(...)guard removed — a 201 becomes a 303, redThree candidate assertions were dropped for failing that bar: a
Headers-constructor Set-Cookie folding claim (modern undici does not fold, so nothing could regress), anexpect(response.body).toBeNull()(guaranteed by the 303 status rather than by anything here), and aURLSearchParamsdecode assertion whose "proof" turned out to be a no-op edit.Suite
packages/webgreen across all three configs;tsc --project packages/web/tsconfig.test.jsonandprettier --checkclean for the new files.Notes
These came out of a coverage comparison against another framework's server-function suite. Solid is ahead almost everywhere — method handling, response shapes, redirects, error sanitization, caching semantics and the CSRF gate are all substantially better covered here — so this PR is only the short list of places where the tree genuinely had nothing.
Two gaps found in that comparison are not addressed here because they are feature questions rather than test gaps: there is no argument-validation API, and
wrapInvocationis a single slot rather than a composable chain. Happy to open issues for either if useful.