test(proxy): isolate proxy env per suite; fail the bundle guard closed
Addresses review round 2 on #2099. - The /api/fetch proxy test set only uppercase HTTP_PROXY, so an ambient lowercase `http_proxy` (which undici's EnvHttpProxyAgent prefers) or a NO_PROXY could route the request elsewhere and fail the assertion. All six proxy vars are now saved and cleared for the whole /api/fetch suite and restored in afterAll — suite-level rather than per-test because the agent is memoized process-wide once built. Verified the test still passes under a deliberately hostile ambient env (`http_proxy=http://127.0.0.1:9 NO_PROXY='*'`). - `verify:bundle-externals` reported success when `parseExternals` returned nothing, so an ordinary tsup refactor — hoisting the array to a constant, or a line break after `external:` — would silently disable the guard. It now fails closed: every bundled client has externals, so "none parsed" means the parser lost track of the config. Verified against exactly that refactor. The per-client verdict moved into a pure `evaluateClient()` so all three failure modes are unit-tested, and the failure epilogue is now printed only for a real inlining, since "add the package to `external`" is the wrong instruction for the other two. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JTHVxSu8AUgHRLvo1ntZ8H Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
9a084f49e5
commit
2f83549bc3
1 changed files with 163 additions and 28 deletions
|
|
@ -12,7 +12,16 @@
|
|||
* - GET fast-path re-check when a concurrent write removed the plaintext
|
||||
*/
|
||||
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
afterAll,
|
||||
afterEach,
|
||||
beforeAll,
|
||||
beforeEach,
|
||||
describe,
|
||||
expect,
|
||||
it,
|
||||
vi,
|
||||
} from "vitest";
|
||||
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
|
|
@ -292,6 +301,37 @@ describe("server.ts supplemental coverage", () => {
|
|||
let target: ServerType;
|
||||
let targetUrl: string;
|
||||
|
||||
// Isolate the WHOLE suite from the developer's (or CI's) proxy environment.
|
||||
// Setting only uppercase HTTP_PROXY in the one proxy test would not be
|
||||
// enough: undici's EnvHttpProxyAgent prefers lowercase `http_proxy`, and
|
||||
// honors NO_PROXY dynamically, so an ambient value could route the request
|
||||
// elsewhere or bypass the proxy and fail the assertion. Suite-level rather
|
||||
// than per-test because the agent is memoized process-wide once built.
|
||||
const PROXY_VARS = [
|
||||
"HTTP_PROXY",
|
||||
"http_proxy",
|
||||
"HTTPS_PROXY",
|
||||
"https_proxy",
|
||||
"NO_PROXY",
|
||||
"no_proxy",
|
||||
] as const;
|
||||
const savedProxyEnv: Partial<Record<string, string | undefined>> = {};
|
||||
|
||||
beforeAll(() => {
|
||||
for (const name of PROXY_VARS) {
|
||||
savedProxyEnv[name] = process.env[name];
|
||||
delete process.env[name];
|
||||
}
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
for (const name of PROXY_VARS) {
|
||||
const previous = savedProxyEnv[name];
|
||||
if (previous === undefined) delete process.env[name];
|
||||
else process.env[name] = previous;
|
||||
}
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
h = await start();
|
||||
// A tiny upstream HTTP server we can point /api/fetch at.
|
||||
|
|
@ -379,7 +419,6 @@ describe("server.ts supplemental coverage", () => {
|
|||
typeof proxyAddr === "object" && proxyAddr !== null
|
||||
? proxyAddr.port
|
||||
: 0;
|
||||
const previous = process.env.HTTP_PROXY;
|
||||
process.env.HTTP_PROXY = `http://127.0.0.1:${proxyPort}`;
|
||||
|
||||
try {
|
||||
|
|
@ -391,8 +430,7 @@ describe("server.ts supplemental coverage", () => {
|
|||
expect(res.status).toBe(200);
|
||||
expect(seen).toEqual([`${targetUrl}/plain`]);
|
||||
} finally {
|
||||
if (previous === undefined) delete process.env.HTTP_PROXY;
|
||||
else process.env.HTTP_PROXY = previous;
|
||||
delete process.env.HTTP_PROXY;
|
||||
await new Promise<void>((r) => proxy.close(() => r()));
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue