fix(studio): poll background generation and handle gateway failures
This commit is contained in:
1 parent
bb40dffee8
commit
3539dff45c
4 files changed
+145
-9
No files matched your search
@@ -0,0 +1,66 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { generationResponse, requestGeneration } from "../src/generation-transport.ts";
|
||||
|
||||
test("HTML gateway failures produce a clear diagnostic rather than a JSON syntax error", async () => {
|
||||
for (const status of [502, 503, 504])
|
||||
await expect(
|
||||
generationResponse(new Response("<html>Gateway error</html>", { status })),
|
||||
).rejects.toThrow(`HTTP ${status}`);
|
||||
await expect(
|
||||
generationResponse(new Response("<html>private proxy text</html>", { status: 504 })),
|
||||
).rejects.not.toThrow("private proxy text");
|
||||
});
|
||||
test("generation uses short job polls and preserves legacy response compatibility", async () => {
|
||||
const batch = { alternatives: [1, 2, 3], diagnostics: [] };
|
||||
let calls = 0;
|
||||
const transport = (async (_url: unknown, init?: RequestInit) => {
|
||||
calls++;
|
||||
if (calls === 1) {
|
||||
expect(new Headers(init?.headers).get("prefer")).toBe("respond-async");
|
||||
return Response.json(
|
||||
{ job: { id: "11111111-1111-4111-8111-111111111111" } },
|
||||
{ status: 202 },
|
||||
);
|
||||
}
|
||||
expect(init?.method).toBeUndefined();
|
||||
return Response.json({ status: "complete", result: batch });
|
||||
}) as unknown as typeof fetch;
|
||||
expect(
|
||||
await requestGeneration(
|
||||
new URL("https://example.test/design-studio/api/generate"),
|
||||
{},
|
||||
new AbortController().signal,
|
||||
transport,
|
||||
),
|
||||
).toEqual(batch);
|
||||
expect(calls).toBe(2);
|
||||
expect(
|
||||
await requestGeneration(
|
||||
new URL("https://example.test/api/generate"),
|
||||
{},
|
||||
new AbortController().signal,
|
||||
(async () => Response.json(batch)) as unknown as typeof fetch,
|
||||
),
|
||||
).toEqual(batch);
|
||||
});
|
||||
test("cancelling a pending job sends cancellation without replacing a draft", async () => {
|
||||
const controller = new AbortController();
|
||||
let cancelled = false;
|
||||
const transport = (async (_url: unknown, init?: RequestInit) => {
|
||||
if (init?.method === "DELETE") {
|
||||
cancelled = true;
|
||||
return Response.json({ status: "cancelled" });
|
||||
}
|
||||
controller.abort();
|
||||
return Response.json({ job: { id: "11111111-1111-4111-8111-111111111111" } }, { status: 202 });
|
||||
}) as unknown as typeof fetch;
|
||||
await expect(
|
||||
requestGeneration(
|
||||
new URL("https://example.test/api/generate"),
|
||||
{},
|
||||
controller.signal,
|
||||
transport,
|
||||
),
|
||||
).rejects.toBeDefined();
|
||||
expect(cancelled).toBe(true);
|
||||
});
|
||||
Reference in new issue
Block a user