Files
agent-desk-ng/web/lib/message-editor-drafts.test.mjs
mono 63e0457886 fix: harden identity, live access, drafts and setup (review only)
Source-reviewed hardening changes and regression tests. UNBUILT / UNTESTED: not a deployable release. Go formatting, compilation, automated regression tests, full frontend validation and staging acceptance remain required. See docs/hardening/VALIDATION.md. Main remains the original clean snapshot; no upstream Git history imported.
2026-10-16 12:15:20 +00:00

100 lines
3.6 KiB
JavaScript

import assert from "node:assert/strict"
import test from "node:test"
import { createMessageEditorDraftStore } from "./message-editor-drafts.ts"
test("conversation drafts stay separate across A → B → A", () => {
const store = createMessageEditorDraftStore()
const a = store.get("1")
store.update(a, "<p>For A</p>")
const b = store.get("2")
assert.equal(b.html, "")
store.update(b, "<p>For B</p>")
assert.equal(store.get("1").html, "<p>For A</p>")
assert.equal(store.get("2").html, "<p>For B</p>")
})
test("failed send preserves text and uploaded image metadata, and can retry", () => {
const store = createMessageEditorDraftStore()
const draft = store.get("1")
store.update(draft, '<p>Message</p><img title="uploading-test">')
draft.uploadedImages.set("uploading-test", { assetId: "test", provider: "local", storageKey: "test", url: "/test" })
assert.equal(store.finishSend(store.beginSend("1"), false), false)
assert.equal(draft.html, '<p>Message</p><img title="uploading-test">')
assert.equal(draft.uploadedImages.size, 1)
assert.ok(store.beginSend("1"))
})
test("send is single-flight, success clears only the captured draft", () => {
const store = createMessageEditorDraftStore()
const a = store.get("1")
const b = store.get("2")
store.update(a, "For A")
store.update(b, "For B")
const sent = store.beginSend("1")
assert.equal(store.beginSend("1"), null)
assert.equal(store.beginSend("2"), null)
assert.equal(store.finishSend(sent, true), true)
assert.equal(a.html, "")
assert.equal(b.html, "For B")
assert.ok(store.beginSend("2"))
})
test("typing during a pending send survives success, even after returning to identical text", () => {
const store = createMessageEditorDraftStore()
const draft = store.get("1")
store.update(draft, "Initial")
const sent = store.beginSend("1")
store.update(draft, "Next draft")
assert.equal(store.finishSend(sent, true), false)
assert.equal(draft.html, "Next draft")
const nextSend = store.beginSend("1")
store.update(draft, "Changed")
store.update(draft, "Next draft")
assert.equal(store.finishSend(nextSend, true), false)
assert.equal(draft.html, "Next draft")
})
test("identity change clears private drafts and invalidates old completions", () => {
const store = createMessageEditorDraftStore()
store.setScope("account-a")
const previous = store.get("1")
store.update(previous, "Private")
const sent = store.beginSend("1")
store.setScope("account-b")
const next = store.get("1")
store.update(next, "New account")
const nextSent = store.beginSend("1")
assert.equal(store.contains("1", previous), false)
assert.equal(store.finishSend(sent, true), false)
assert.equal(next.html, "New account")
assert.equal(store.finishSend(nextSent, true), true)
})
test("a newly mounted editor observes completion from the previous editor instance", () => {
const store = createMessageEditorDraftStore()
const draft = store.get("1")
store.update(draft, "Pending")
const sent = store.beginSend("1")
let rendered = draft.html
const unsubscribe = store.subscribe((changed) => {
if (changed === draft) rendered = changed.html
})
store.finishSend(sent, true)
assert.equal(rendered, "")
unsubscribe()
})
test("pending status stays observable when switching or remounting editors", () => {
const store = createMessageEditorDraftStore()
store.get("1")
const states = []
const unsubscribe = store.subscribeSending(() => states.push(store.isSending()))
const sent = store.beginSend("1")
store.get("2")
assert.equal(store.isSending(), true)
store.finishSend(sent, false)
assert.deepEqual(states, [true, false])
unsubscribe()
})