Add support for message history pagination, preserve scroll in rendering, and improve draft/message workflows.
CI / check (22) (push) Successful in 9m34s
CI / check (24) (push) Successful in 9m34s

This commit is contained in:
2026-10-06 00:32:18 +02:00
parent 1c0f06716e
commit 387c0ac2e7
40 changed files with 2374 additions and 1314 deletions
+25 -1
View File
@@ -1,6 +1,30 @@
import test from "node:test";
import assert from "node:assert/strict";
import {ApiError, get, post, stream} from "../public/js/api.js";
import {ApiError, get, post, stream, multipart, download} from "../public/js/api.js";
test("multipart and downloads share HTTP checks, cancellation and body deadlines", async t => {
const form = new FormData(); form.append("image", new Blob(["image"]), "image.png");
t.mock.method(globalThis, "fetch", async (_url, options) => {
assert.equal(options.body, form);
assert.equal(options.headers["Content-Type"], undefined);
return Response.json({id: "uploaded"});
});
assert.deepEqual(await multipart("/uploads", form), {id: "uploaded"});
t.mock.method(globalThis, "fetch", async () => Response.json({error: "Please log in", code: "LOGIN_REQUIRED"}, {status: 403}));
const failed = await download("/export");
assert.equal(failed.code, "LOGIN_REQUIRED");
assert.equal(failed.blob, undefined);
t.mock.method(globalThis, "fetch", async () => new Response("download content"));
assert.equal(await (await download("/export")).blob.text(), "download content");
t.mock.method(globalThis, "fetch", async () => new Response(new ReadableStream()));
assert.equal((await download("/stalled", {timeoutMs: 10})).code, "TIMEOUT");
t.mock.method(globalThis, "fetch", async () => new Promise(() => {}));
const controller = new AbortController();
const pending = multipart("/upload", form, {signal: controller.signal});
controller.abort();
assert.equal((await pending).code, "ABORTED");
assert.equal((await multipart("/upload", form, {timeoutMs: 10})).code, "TIMEOUT");
});
test("JSON requests retain HTTP metadata, handle empty success, and distinguish bad bodies from network errors", async t => {
let response;