import { assertEquals } from "@std/assert"; import type { SubmissionId } from "@earendil-works/pi-durable"; import type { UserMessage } from "@earendil-works/pi-ai"; import { IDBFactory } from "fake-indexeddb"; import { PNG, until } from "@berry/util"; import { withDom } from "@berry/util/dom.ts"; import { stoppedInputs } from "./stopped-inputs.tsx"; import { Scope } from "./ui.ts"; Deno.test("stopped messages survive navigation and reload with attachments until restored or dismissed", async () => { await withDom(async (window) => { const tid = "stopped-drafts"; const content: UserMessage["content"] = [ { type: "text", text: "Keep the picture" }, { type: "image", mimeType: "image/png", data: PNG }, ]; const scope = new Scope(); const first = stoppedInputs(scope, tid, () => Promise.resolve(false), () => {}); document.body.append(first.element); await first.recover([ { id: 1 as SubmissionId, mode: "steer", content }, { id: 2 as SubmissionId, mode: "followUp", content: "Another message" }, ]); scope.dispose(); first.element.remove(); const fresh = await import( new URL("./stopped-inputs.tsx?reload", import.meta.url).href ) as typeof import("./stopped-inputs.tsx"); const restored: UserMessage["content"][] = []; const reopenedScope = new Scope(); try { const reopened = fresh.stoppedInputs(reopenedScope, tid, (value) => { restored.push(value); return Promise.resolve(true); }, () => {}); document.body.append(reopened.element); await until(() => reopened.element.querySelectorAll(".queued").length === 2); reopened.element.querySelector("button")!.click(); await until(() => reopened.element.querySelectorAll(".queued").length === 1); assertEquals(restored, [content]); const dismiss = [...reopened.element.querySelectorAll("button")].find((button) => button.textContent === "Dismiss" )!; dismiss.click(); await window.happyDOM.waitUntilComplete(); assertEquals(reopened.element.hidden, true); } finally { reopenedScope.dispose(); } }, { globals: { indexedDB: new IDBFactory() } }); });