| 1 | import assert from "node:assert/strict"; |
| 2 | import React, { act } from "react"; |
| 3 | import { createRoot } from "react-dom/client"; |
| 4 | import { JSDOM } from "jsdom"; |
| 5 | import { installDesktopHostStub } from "./desktopHostStub"; |
| 6 | import { useExtensionSurface } from "../app-runtime/useExtensionSurface"; |
| 7 | |
| 8 | const dom = new JSDOM("<div id='root'></div>", { url: "http://localhost" }); |
| 9 | Object.assign(globalThis, { window: dom.window, document: dom.window.document, IS_REACT_ACT_ENVIRONMENT: true }); |
| 10 | const calls: Array<{ generation: number; values: Record<string, unknown> }> = []; |
| 11 | const errors: string[] = []; |
| 12 | const stub = installDesktopHostStub({ SubmitExtensionFormExact: async (target, values) => { |
| 13 | calls.push({ generation: target.sessionGeneration, values }); |
| 14 | } }); |
| 15 | let surface!: ReturnType<typeof useExtensionSurface>; |
| 16 | function Probe({ generation }: { generation?: number }) { |
| 17 | surface = useExtensionSurface({ activeTabId: "A", sessionId: "session-A", sessionGeneration: generation, |
| 18 | form: { pluginId: "fixture", surfaceId: "form", generation: 1, formInstanceId: "form-1", formInstanceExact: true }, |
| 19 | notifications: [], dismissForm: () => {}, drainNotifications: () => {}, showToast: text => { errors.push(text); } }); |
| 20 | return null; |
| 21 | } |
| 22 | const root = createRoot(document.getElementById("root")!); |
| 23 | try { |
| 24 | await act(async () => root.render(<Probe generation={0} />)); |
| 25 | await act(async () => { await surface.submitExtensionForm({ value: "fixture" }); }); |
| 26 | await act(async () => { await surface.cancelExtensionForm(); }); |
| 27 | assert.deepEqual(calls, [{ generation: 0, values: { value: "fixture" } }, { generation: 0, values: { cancelled: true } }]); |
| 28 | assert.equal(errors.length, 0, "the first session can submit and cancel forms"); |
| 29 | await act(async () => root.render(<Probe />)); |
| 30 | await act(async () => { await surface.submitExtensionForm({ value: "stale" }); }); |
| 31 | await act(async () => { await surface.cancelExtensionForm(); }); |
| 32 | assert.equal(calls.length, 2, "an absent generation is never synthesized as the initial generation"); |
| 33 | assert.equal(errors.length, 1); |
| 34 | console.log("extension initial binding: generation zero allowed; missing binding fenced"); |
| 35 | } finally { |
| 36 | await act(async () => root.unmount()); stub.uninstall(); dom.window.close(); |
| 37 | } |
| 38 |