74 lines
2.3 KiB
TypeScript
74 lines
2.3 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import type { BrowserRouteContext } from "../server-context.js";
|
|
|
|
vi.mock("./index.js", () => {
|
|
return {
|
|
registerBrowserRoutes(app: { get: (path: string, handler: unknown) => void }) {
|
|
app.get(
|
|
"/slow",
|
|
async (req: { signal?: AbortSignal }, res: { json: (body: unknown) => void }) => {
|
|
const signal = req.signal;
|
|
await new Promise<void>((resolve, reject) => {
|
|
if (signal?.aborted) {
|
|
reject(signal.reason ?? new Error("aborted"));
|
|
return;
|
|
}
|
|
const onAbort = () => reject(signal?.reason ?? new Error("aborted"));
|
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
queueMicrotask(() => {
|
|
signal?.removeEventListener("abort", onAbort);
|
|
resolve();
|
|
});
|
|
});
|
|
res.json({ ok: true });
|
|
},
|
|
);
|
|
app.get(
|
|
"/echo/:id",
|
|
async (
|
|
req: { params?: Record<string, string> },
|
|
res: { json: (body: unknown) => void },
|
|
) => {
|
|
res.json({ id: req.params?.id ?? null });
|
|
},
|
|
);
|
|
},
|
|
};
|
|
});
|
|
|
|
describe("browser route dispatcher (abort)", () => {
|
|
it("propagates AbortSignal and lets handlers observe abort", async () => {
|
|
const { createBrowserRouteDispatcher } = await import("./dispatcher.js");
|
|
const dispatcher = createBrowserRouteDispatcher({} as BrowserRouteContext);
|
|
|
|
const ctrl = new AbortController();
|
|
const promise = dispatcher.dispatch({
|
|
method: "GET",
|
|
path: "/slow",
|
|
signal: ctrl.signal,
|
|
});
|
|
|
|
ctrl.abort(new Error("timed out"));
|
|
|
|
await expect(promise).resolves.toMatchObject({
|
|
status: 500,
|
|
body: { error: expect.stringContaining("timed out") },
|
|
});
|
|
});
|
|
|
|
it("returns 400 for malformed percent-encoding in route params", async () => {
|
|
const { createBrowserRouteDispatcher } = await import("./dispatcher.js");
|
|
const dispatcher = createBrowserRouteDispatcher({} as BrowserRouteContext);
|
|
|
|
await expect(
|
|
dispatcher.dispatch({
|
|
method: "GET",
|
|
path: "/echo/%E0%A4%A",
|
|
}),
|
|
).resolves.toMatchObject({
|
|
status: 400,
|
|
body: { error: expect.stringContaining("invalid path parameter encoding") },
|
|
});
|
|
});
|
|
});
|