Files
Dorod-Sky/skyvern-ts/client/tests/mock-server/MockServerPool.ts
2025-10-23 20:14:59 -06:00

107 lines
3.7 KiB
TypeScript

import { setupServer } from "msw/node";
import { fromJson, toJson } from "../../src/core/json";
import { MockServer } from "./MockServer";
import { randomBaseUrl } from "./randomBaseUrl";
const mswServer = setupServer();
interface MockServerOptions {
baseUrl?: string;
}
async function formatHttpRequest(request: Request, id?: string): Promise<string> {
try {
const clone = request.clone();
const headers = [...clone.headers.entries()].map(([k, v]) => `${k}: ${v}`).join("\n");
let body = "";
try {
const contentType = clone.headers.get("content-type");
if (contentType?.includes("application/json")) {
body = toJson(fromJson(await clone.text()), undefined, 2);
} else if (clone.body) {
body = await clone.text();
}
} catch (_e) {
body = "(unable to parse body)";
}
const title = id ? `### Request ${id} ###\n` : "";
const firstLine = `${title}${request.method} ${request.url.toString()} HTTP/1.1`;
return `\n${firstLine}\n${headers}\n\n${body || "(no body)"}\n`;
} catch (e) {
return `Error formatting request: ${e}`;
}
}
async function formatHttpResponse(response: Response, id?: string): Promise<string> {
try {
const clone = response.clone();
const headers = [...clone.headers.entries()].map(([k, v]) => `${k}: ${v}`).join("\n");
let body = "";
try {
const contentType = clone.headers.get("content-type");
if (contentType?.includes("application/json")) {
body = toJson(fromJson(await clone.text()), undefined, 2);
} else if (clone.body) {
body = await clone.text();
}
} catch (_e) {
body = "(unable to parse body)";
}
const title = id ? `### Response for ${id} ###\n` : "";
const firstLine = `${title}HTTP/1.1 ${response.status} ${response.statusText}`;
return `\n${firstLine}\n${headers}\n\n${body || "(no body)"}\n`;
} catch (e) {
return `Error formatting response: ${e}`;
}
}
class MockServerPool {
private servers: MockServer[] = [];
public createServer(options?: Partial<MockServerOptions>): MockServer {
const baseUrl = options?.baseUrl || randomBaseUrl();
const server = new MockServer({ baseUrl, server: mswServer });
this.servers.push(server);
return server;
}
public getServers(): MockServer[] {
return [...this.servers];
}
public listen(): void {
const onUnhandledRequest = process.env.LOG_LEVEL === "debug" ? "warn" : "bypass";
mswServer.listen({ onUnhandledRequest });
if (process.env.LOG_LEVEL === "debug") {
mswServer.events.on("request:start", async ({ request, requestId }) => {
const formattedRequest = await formatHttpRequest(request, requestId);
console.debug(`request:start\n${formattedRequest}`);
});
mswServer.events.on("request:unhandled", async ({ request, requestId }) => {
const formattedRequest = await formatHttpRequest(request, requestId);
console.debug(`request:unhandled\n${formattedRequest}`);
});
mswServer.events.on("response:mocked", async ({ request, response, requestId }) => {
const formattedResponse = await formatHttpResponse(response, requestId);
console.debug(`response:mocked\n${formattedResponse}`);
});
}
}
public close(): void {
this.servers = [];
mswServer.close();
}
}
export const mockServerPool = new MockServerPool();