Spaces:
Configuration error
Configuration error
| import type { IncomingMessage, ServerResponse } from "node:http"; | |
| import { describe, expect, it, vi } from "vitest"; | |
| import { createGatewayPluginRequestHandler } from "./plugins-http.js"; | |
| import { createTestRegistry } from "./__tests__/test-utils.js"; | |
| const makeResponse = (): { | |
| res: ServerResponse; | |
| setHeader: ReturnType<typeof vi.fn>; | |
| end: ReturnType<typeof vi.fn>; | |
| } => { | |
| const setHeader = vi.fn(); | |
| const end = vi.fn(); | |
| const res = { | |
| headersSent: false, | |
| statusCode: 200, | |
| setHeader, | |
| end, | |
| } as unknown as ServerResponse; | |
| return { res, setHeader, end }; | |
| }; | |
| describe("createGatewayPluginRequestHandler", () => { | |
| it("returns false when no handlers are registered", async () => { | |
| const log = { warn: vi.fn() } as unknown as Parameters< | |
| typeof createGatewayPluginRequestHandler | |
| >[0]["log"]; | |
| const handler = createGatewayPluginRequestHandler({ | |
| registry: createTestRegistry(), | |
| log, | |
| }); | |
| const { res } = makeResponse(); | |
| const handled = await handler({} as IncomingMessage, res); | |
| expect(handled).toBe(false); | |
| }); | |
| it("continues until a handler reports it handled the request", async () => { | |
| const first = vi.fn(async () => false); | |
| const second = vi.fn(async () => true); | |
| const handler = createGatewayPluginRequestHandler({ | |
| registry: createTestRegistry({ | |
| httpHandlers: [ | |
| { pluginId: "first", handler: first, source: "first" }, | |
| { pluginId: "second", handler: second, source: "second" }, | |
| ], | |
| }), | |
| log: { warn: vi.fn() } as unknown as Parameters< | |
| typeof createGatewayPluginRequestHandler | |
| >[0]["log"], | |
| }); | |
| const { res } = makeResponse(); | |
| const handled = await handler({} as IncomingMessage, res); | |
| expect(handled).toBe(true); | |
| expect(first).toHaveBeenCalledTimes(1); | |
| expect(second).toHaveBeenCalledTimes(1); | |
| }); | |
| it("handles registered http routes before generic handlers", async () => { | |
| const routeHandler = vi.fn(async (_req, res: ServerResponse) => { | |
| res.statusCode = 200; | |
| }); | |
| const fallback = vi.fn(async () => true); | |
| const handler = createGatewayPluginRequestHandler({ | |
| registry: createTestRegistry({ | |
| httpRoutes: [ | |
| { | |
| pluginId: "route", | |
| path: "/demo", | |
| handler: routeHandler, | |
| source: "route", | |
| }, | |
| ], | |
| httpHandlers: [{ pluginId: "fallback", handler: fallback, source: "fallback" }], | |
| }), | |
| log: { warn: vi.fn() } as unknown as Parameters< | |
| typeof createGatewayPluginRequestHandler | |
| >[0]["log"], | |
| }); | |
| const { res } = makeResponse(); | |
| const handled = await handler({ url: "/demo" } as IncomingMessage, res); | |
| expect(handled).toBe(true); | |
| expect(routeHandler).toHaveBeenCalledTimes(1); | |
| expect(fallback).not.toHaveBeenCalled(); | |
| }); | |
| it("logs and responds with 500 when a handler throws", async () => { | |
| const log = { warn: vi.fn() } as unknown as Parameters< | |
| typeof createGatewayPluginRequestHandler | |
| >[0]["log"]; | |
| const handler = createGatewayPluginRequestHandler({ | |
| registry: createTestRegistry({ | |
| httpHandlers: [ | |
| { | |
| pluginId: "boom", | |
| handler: async () => { | |
| throw new Error("boom"); | |
| }, | |
| source: "boom", | |
| }, | |
| ], | |
| }), | |
| log, | |
| }); | |
| const { res, setHeader, end } = makeResponse(); | |
| const handled = await handler({} as IncomingMessage, res); | |
| expect(handled).toBe(true); | |
| expect(log.warn).toHaveBeenCalledWith(expect.stringContaining("boom")); | |
| expect(res.statusCode).toBe(500); | |
| expect(setHeader).toHaveBeenCalledWith("Content-Type", "text/plain; charset=utf-8"); | |
| expect(end).toHaveBeenCalledWith("Internal Server Error"); | |
| }); | |
| }); | |