feat(chat): preserve message drafts in session temp store
This commit is contained in:
@@ -3,6 +3,7 @@ const assert = require('node:assert/strict')
|
||||
const fs = require('node:fs')
|
||||
const vm = require('node:vm')
|
||||
const vue = require('vue')
|
||||
const { createDraftHarness } = require('./helpers/chat-drafts.cjs')
|
||||
const settle = () => new Promise(setImmediate)
|
||||
const deferred = () => { let resolve; return { promise: new Promise(done => { resolve = done }), resolve: value => resolve(value) } }
|
||||
|
||||
@@ -89,3 +90,62 @@ test('image display rejects external URLs and ignores responses after a room cha
|
||||
await ui.run('load()')
|
||||
assert.equal(ui.run('dataUrl.value'), 'data:image/webp;base64,AAAA')
|
||||
})
|
||||
|
||||
function collaborationApi(onSend) {
|
||||
return async (url, options) => {
|
||||
if (options?.method === 'POST' && url.endsWith('/messages')) return onSend(options.body)
|
||||
if (url.endsWith('/messages')) return { messages: [], hasMore: false }
|
||||
if (url.endsWith('/members')) return { members: [] }
|
||||
if (url.endsWith('/read')) return {}
|
||||
return { canSend: true, name: 'Partnerchat' }
|
||||
}
|
||||
}
|
||||
|
||||
test('collaboration drafts retain text, images and the retry ID when reopening after a failed send', async t => {
|
||||
const drafts = createDraftHarness(), attempts = []
|
||||
t.after(drafts.close)
|
||||
let fail = true
|
||||
const props = { roomId: 'shared', base: '/api/collaboration', api: collaborationApi(body => {
|
||||
attempts.push(body)
|
||||
if (fail) throw { data: { message: 'Offline' } }
|
||||
return { id: 'message-1', seq: 1, own: true, clientId: body.clientId, body: body.text }
|
||||
}) }
|
||||
const first = setup('CollaborationRoom', props, { useChatDraft: drafts.useChatDraft })
|
||||
await settle()
|
||||
first.run('draft.value = " Partnerentwurf\\n "; draftImage.value = { dataUrl: "data:image/webp;base64,AAAA", name: "Plan" }')
|
||||
await first.run('send()')
|
||||
assert.equal(first.run('draft.value'), ' Partnerentwurf\n ')
|
||||
assert.equal(first.run('draftImage.value.name'), 'Plan')
|
||||
await first.run('load()')
|
||||
assert.equal(first.run('draft.value'), ' Partnerentwurf\n ')
|
||||
first.close()
|
||||
const second = setup('CollaborationRoom', props, { useChatDraft: drafts.useChatDraft })
|
||||
t.after(second.close)
|
||||
await settle()
|
||||
assert.equal(second.run('draft.value'), ' Partnerentwurf\n ')
|
||||
fail = false
|
||||
await second.run('send()')
|
||||
assert.equal(attempts[0].clientId, attempts[1].clientId)
|
||||
assert.equal(second.run('draft.value'), '')
|
||||
assert.equal(second.run('draftImage.value'), null)
|
||||
assert.equal(Object.keys(drafts.storage).length, 0)
|
||||
})
|
||||
|
||||
test('collaboration send completion after unmount does not erase a newer draft in the same room', async t => {
|
||||
const drafts = createDraftHarness(), pending = deferred()
|
||||
t.after(drafts.close)
|
||||
const props = { roomId: 'shared', base: '/api/collaboration', api: collaborationApi(() => pending.promise) }
|
||||
const first = setup('CollaborationRoom', props, { useChatDraft: drafts.useChatDraft })
|
||||
await settle()
|
||||
first.run('draft.value = "Gesendet"')
|
||||
const sending = first.run('send()')
|
||||
first.close()
|
||||
const second = setup('CollaborationRoom', props, { useChatDraft: drafts.useChatDraft })
|
||||
t.after(second.close)
|
||||
await settle()
|
||||
second.run('draft.value = "Neuer Entwurf"')
|
||||
pending.resolve({ id: 'message-1', seq: 1, body: 'Gesendet' })
|
||||
await sending
|
||||
assert.equal(second.run('draft.value'), 'Neuer Entwurf')
|
||||
assert.equal(second.run('messages.value.length'), 0)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user