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, '') })