Files
next-ai-draw-io/tests/unit/parse-url-route.test.ts
T
dayuan.jiang 50c7ad3ec4 fix(server): keep users' keys at their own endpoints, and more fixes from the third review
- Bedrock: a user's AWS keys no longer go to an endpoint the server sets
  in AWS_ENDPOINT_URL_BEDROCK_RUNTIME / AWS_ENDPOINT_URL (read by the
  upgraded SDK), and admin panel keys win over AWS_BEARER_TOKEN_BEDROCK,
  as the Test button checks them. Checked with Bedrock.
- Ollama: a server key without a base URL (admin panel, OLLAMA_API_KEY)
  goes to Ollama Cloud, as env.example says, instead of 127.0.0.1.
- Quota: EdgeOne counts whatever key header comes along, keyless Ollama at
  a private address counts, and their provider texts stay in the log.
- An EdgeOne server model (admin panel, ai-models.json) works: the route
  checked the raw provider header, which holds the name's slug.
- parse-url ends downloads it does not read (too large, PDF, errors).
- Desktop app: the port follows where the chats are (IndexedDB per
  origin) instead of a remembered port, which could hide them for good;
  a same-port restart tells the page to refetch the server models; a
  failed preset switch no longer undoes a newer choice; a presets file
  removed after a failed read can be saved again; .env values quoted from
  start to end keep their inner quotes, as dotenv reads them.
2026-10-05 13:04:51 +09:00

42 lines
1.4 KiB
TypeScript

// @vitest-environment node
import { afterEach, describe, expect, it, vi } from "vitest"
import { POST as parseUrl } from "@/app/api/parse-url/route"
// Treat every URL as public so no test hits DNS
vi.mock("@/lib/ssrf-protection", async (importOriginal) => ({
...(await importOriginal<typeof import("@/lib/ssrf-protection")>()),
isPrivateUrl: async () => false,
}))
afterEach(() => {
vi.unstubAllGlobals()
})
describe("POST /api/parse-url", () => {
it("stops the download of a page announced as too large", async () => {
let signal: AbortSignal | undefined
vi.stubGlobal(
"fetch",
vi.fn(async (_url: string, init: RequestInit) => {
signal = init.signal ?? undefined
// A body that never ends unless the request is aborted
return new Response(new ReadableStream(), {
headers: {
"content-type": "text/html",
"content-length": String(50 * 1024 * 1024),
},
})
}),
)
const res = await parseUrl(
new Request("http://localhost/api/parse-url", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ url: "https://example.com/huge" }),
}),
)
expect(res.status).toBe(413)
expect(signal?.aborted).toBe(true)
})
})