mirror of
https://github.com/openclaw/openclaw.git
synced 2026-09-28 05:54:09 +08:00
fix(test): stop preflight mocks leaking into shared workers (#157207)
This commit is contained in:
@@ -2,7 +2,11 @@ import { createServer } from "node:http";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { assertUiE2ePreflight } from "./vitest/vitest.ui-e2e-preflight.ts";
|
||||
|
||||
vi.mock("node:http", { spy: true });
|
||||
vi.mock("node:http", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("node:http")>();
|
||||
// Native HTTP and socket prototypes outlive a test file in shared workers.
|
||||
return { ...actual, createServer: vi.fn(actual.createServer) };
|
||||
});
|
||||
|
||||
const listeners: Array<{
|
||||
server: ReturnType<typeof createServer>;
|
||||
@@ -22,14 +26,19 @@ beforeEach(async () => {
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
// Keep a failed cleanup assertion from leaking its real listener into later tests.
|
||||
for (const { server } of listeners) {
|
||||
server.closeAllConnections();
|
||||
if (server.listening) {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
server.close((error) => (error ? reject(error) : resolve()));
|
||||
});
|
||||
try {
|
||||
// Keep a failed cleanup assertion from leaking its real listener into later tests.
|
||||
for (const { server } of listeners) {
|
||||
server.closeAllConnections();
|
||||
if (server.listening) {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
server.close((error) => (error ? reject(error) : resolve()));
|
||||
});
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
// restoreAllMocks does not reset module spies' custom implementations.
|
||||
vi.mocked(createServer).mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -43,6 +52,35 @@ function expectListenerClosed() {
|
||||
}
|
||||
|
||||
describe("UI E2E environment preflight", () => {
|
||||
it("preserves native HTTP and socket implementations for later shared-worker consumers", () => {
|
||||
const nativeHttp = process.getBuiltinModule("node:http");
|
||||
const nativeNet = process.getBuiltinModule("node:net");
|
||||
for (const implementation of [
|
||||
nativeHttp.Server,
|
||||
nativeHttp.Agent,
|
||||
nativeHttp.IncomingMessage,
|
||||
nativeHttp.OutgoingMessage,
|
||||
nativeHttp.ServerResponse,
|
||||
nativeHttp.ClientRequest,
|
||||
nativeHttp.createServer,
|
||||
nativeNet.Socket,
|
||||
]) {
|
||||
expect(vi.isMockFunction(implementation)).toBe(false);
|
||||
}
|
||||
for (const [prototype, method] of [
|
||||
[nativeHttp.IncomingMessage.prototype, "read"],
|
||||
[nativeHttp.OutgoingMessage.prototype, "write"],
|
||||
[nativeHttp.OutgoingMessage.prototype, "end"],
|
||||
[nativeHttp.globalAgent, "createConnection"],
|
||||
[nativeNet.Socket.prototype, "write"],
|
||||
] as const) {
|
||||
expect(prototype).toHaveProperty(
|
||||
method,
|
||||
expect.toSatisfy((implementation) => !vi.isMockFunction(implementation)),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("proves the owned HTTP response and releases its listener", async () => {
|
||||
const fetchImpl = vi.fn<typeof fetch>(fetch);
|
||||
await assertUiE2ePreflight({ fetchImpl });
|
||||
|
||||
Reference in New Issue
Block a user