feat(chat): preserve message drafts in session temp store
This commit is contained in:
123
frontend/tests/chat-drafts.test.cjs
Normal file
123
frontend/tests/chat-drafts.test.cjs
Normal file
@@ -0,0 +1,123 @@
|
||||
const { test } = require('node:test')
|
||||
const assert = require('node:assert/strict')
|
||||
const vue = require('vue')
|
||||
const { createDraftHarness, memoryStorage } = require('./helpers/chat-drafts.cjs')
|
||||
const image = { dataUrl: 'data:image/webp;base64,AAAA', name: 'Skizze.webp' }
|
||||
|
||||
test('text and image drafts survive room changes and a browser reload in the same session', t => {
|
||||
const storage = memoryStorage(), first = createDraftHarness({ storage })
|
||||
t.after(first.close)
|
||||
const room = vue.ref('allgemein'), composer = first.useChatDraft(room)
|
||||
composer.draft.value = ' Hallo\nWelt 👋 '
|
||||
composer.draftImage.value = image
|
||||
room.value = 'project_1'
|
||||
assert.equal(composer.draft.value, '')
|
||||
assert.equal(composer.draftImage.value, null)
|
||||
composer.draft.value = 'Projektentwurf'
|
||||
room.value = 'allgemein'
|
||||
assert.equal(composer.draft.value, ' Hallo\nWelt 👋 ')
|
||||
assert.equal(composer.draftImage.value.name, image.name)
|
||||
|
||||
const reloaded = createDraftHarness({ storage })
|
||||
t.after(reloaded.close)
|
||||
const restored = reloaded.useChatDraft('allgemein')
|
||||
assert.equal(restored.draft.value, composer.draft.value)
|
||||
assert.equal(restored.draftImage.value.dataUrl, image.dataUrl)
|
||||
assert.equal(restored.captureDraft().value.clientId, composer.captureDraft().value.clientId)
|
||||
assert.equal(reloaded.useChatDraft('project_1').draft.value, 'Projektentwurf')
|
||||
assert.equal(first.calls.length, 0)
|
||||
})
|
||||
|
||||
test('tenant and profile scopes cannot read each other; logout removes the session drafts', t => {
|
||||
const ui = createDraftHarness()
|
||||
t.after(ui.close)
|
||||
const composer = ui.useChatDraft('allgemein')
|
||||
composer.draft.value = 'Privater Entwurf'
|
||||
ui.auth.activeTenant = '2'
|
||||
assert.equal(composer.draft.value, '')
|
||||
composer.draft.value = 'Mandant 2'
|
||||
ui.auth.activeTenant = '1'
|
||||
assert.equal(composer.draft.value, 'Privater Entwurf')
|
||||
ui.auth.profile = { id: 'other-profile' }
|
||||
assert.equal(composer.draft.value, '')
|
||||
ui.auth.profile = { id: 'profile-1' }
|
||||
assert.equal(composer.draft.value, 'Privater Entwurf')
|
||||
ui.auth.user = { id: 'another-user' }
|
||||
assert.equal(composer.draft.value, '')
|
||||
assert.equal(Object.keys(ui.storage).length, 0)
|
||||
composer.draft.value = 'Neuer Benutzer'
|
||||
ui.auth.user = null
|
||||
assert.equal(composer.draft.value, '')
|
||||
assert.equal(Object.keys(ui.storage).length, 0)
|
||||
})
|
||||
|
||||
test('successful sends remove only the captured version, even after changing rooms', t => {
|
||||
const ui = createDraftHarness()
|
||||
t.after(ui.close)
|
||||
const room = vue.ref('allgemein'), composer = ui.useChatDraft(room)
|
||||
composer.draft.value = 'Gesendet'
|
||||
const sent = composer.captureDraft()
|
||||
room.value = 'project_1'
|
||||
composer.draft.value = 'Noch nicht gesendet'
|
||||
composer.clearDraft(sent)
|
||||
assert.equal(composer.draft.value, 'Noch nicht gesendet')
|
||||
room.value = 'allgemein'
|
||||
assert.equal(composer.draft.value, '')
|
||||
composer.draftImage.value = image
|
||||
const older = composer.captureDraft()
|
||||
composer.draft.value = 'Neuer Text zum Bild'
|
||||
composer.clearDraft(older)
|
||||
assert.equal(composer.draft.value, 'Neuer Text zum Bild')
|
||||
assert.equal(composer.draftImage.value.name, image.name)
|
||||
composer.clearDraft(composer.captureDraft())
|
||||
assert.equal(composer.draft.value, '')
|
||||
assert.equal(composer.draftImage.value, null)
|
||||
})
|
||||
|
||||
test('empty drafts are removed and never enter the shared profile temp_config', async t => {
|
||||
const ui = createDraftHarness()
|
||||
t.after(ui.close)
|
||||
const composer = ui.useChatDraft('direct_user-2')
|
||||
composer.draft.value = 'Geheim'
|
||||
ui.store.modifySearchString('contacts', 'Beispiel')
|
||||
assert.equal(JSON.stringify(ui.calls).includes('Geheim'), false)
|
||||
ui.store.setStoredTempConfig({ settings: { density: 'compact' } })
|
||||
assert.equal(composer.draft.value, 'Geheim')
|
||||
composer.draft.value = ''
|
||||
assert.equal(Object.keys(ui.storage).length, 0)
|
||||
})
|
||||
|
||||
test('guest conversations never reuse internal drafts and keep temporary text through a retry', t => {
|
||||
const ui = createDraftHarness()
|
||||
t.after(ui.close)
|
||||
ui.useChatDraft('collaboration:one').draft.value = 'Interner Entwurf'
|
||||
const room = vue.ref('collaboration:one'), guest = ui.useChatDraft(room, { persist: false })
|
||||
assert.equal(guest.draft.value, '')
|
||||
guest.draft.value = 'Gastentwurf'
|
||||
assert.equal(guest.draft.value, 'Gastentwurf')
|
||||
room.value = 'collaboration:two'
|
||||
assert.equal(guest.draft.value, '')
|
||||
assert.equal(Object.values(ui.storage).some(value => value.includes('Gastentwurf')), false)
|
||||
})
|
||||
|
||||
test('corrupt or unavailable browser storage does not prevent writing or sending', t => {
|
||||
const storage = memoryStorage(), initial = createDraftHarness({ storage })
|
||||
t.after(initial.close)
|
||||
initial.useChatDraft('allgemein').draft.value = 'Alt'
|
||||
storage[Object.keys(storage)[0]] = 'invalid json'
|
||||
const corrupt = createDraftHarness({ storage })
|
||||
t.after(corrupt.close)
|
||||
assert.equal(corrupt.useChatDraft('allgemein').draft.value, '')
|
||||
const blocked = createDraftHarness({ storage: {
|
||||
getItem() { throw Error('Blocked') }, setItem() { throw Error('Quota exceeded') }, removeItem() { throw Error('Blocked') },
|
||||
} })
|
||||
t.after(blocked.close)
|
||||
const composer = blocked.useChatDraft('allgemein')
|
||||
composer.draft.value = 'Im Speicher'
|
||||
composer.draftImage.value = image
|
||||
assert.equal(composer.draft.value, 'Im Speicher')
|
||||
assert.equal(composer.draftImage.value.name, image.name)
|
||||
assert.equal(blocked.toasts.length, 1)
|
||||
composer.clearDraft(composer.captureDraft())
|
||||
assert.equal(composer.draft.value, '')
|
||||
})
|
||||
Reference in New Issue
Block a user