Source-only publication of reviewed commit 64e96a7f423673dc29ad56485be9fc79bce8af1c.
Passed in isolation: focused frontend/backend tests, race checks, TypeScript typecheck, lint, Go compilation, Flowgram build, and deterministic SDK build/tests.
Not accepted as a production release: Next.js export/native assembly remains blocked by environment memory limits; browser interaction and MySQL staging acceptance remain unverified. No production server, database/schema, runtime configuration, deployment, release tag, or workflow execution was performed.
Expected source tree: 0a4a7528e9.
100 lines
3.6 KiB
JavaScript
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()
|
|
})
|