test(desktop): cover undefined/null attachment holes in ref helpers

Regression for the refText crash: attachmentDisplayText and
optimisticAttachmentRef must return null (not throw) when handed an
undefined/null attachment hole, so the submit path can't reproduce
"Cannot read properties of undefined (reading 'refText')".
This commit is contained in:
xxxigm 2026-06-25 00:05:48 +07:00 committed by Teknium
parent 7e2db0a140
commit 4aeaba6922

View file

@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest'
import type { ComposerAttachment } from '@/store/composer'
import { coerceThinkingText, optimisticAttachmentRef, parseCommandDispatch } from './chat-runtime'
import { attachmentDisplayText, coerceThinkingText, optimisticAttachmentRef, parseCommandDispatch } from './chat-runtime'
const DATA_URL = 'data:image/png;base64,iVBORw0KGgoAAAANS'
@ -36,6 +36,32 @@ describe('optimisticAttachmentRef', () => {
'@file:src/a.ts'
)
})
// Session switches / draft restores can leave undefined|null holes in the
// composer attachments array. AttachmentList already filters them (#49624),
// but the submit path maps the same array through these helpers — an unguarded
// hole threw "Cannot read properties of undefined (reading 'refText')",
// crashing the chat surface (blank pane). The helpers must no-op on holes.
it('returns null for an undefined attachment instead of throwing', () => {
expect(() => optimisticAttachmentRef(undefined as unknown as ComposerAttachment)).not.toThrow()
expect(optimisticAttachmentRef(undefined as unknown as ComposerAttachment)).toBeNull()
})
it('returns null for a null attachment instead of throwing', () => {
expect(optimisticAttachmentRef(null as unknown as ComposerAttachment)).toBeNull()
})
})
describe('attachmentDisplayText', () => {
it('returns null for undefined|null instead of reading .kind/.refText on a hole', () => {
expect(() => attachmentDisplayText(undefined as unknown as ComposerAttachment)).not.toThrow()
expect(attachmentDisplayText(undefined as unknown as ComposerAttachment)).toBeNull()
expect(attachmentDisplayText(null as unknown as ComposerAttachment)).toBeNull()
})
it('still resolves a normal file ref', () => {
expect(attachmentDisplayText(attachment({ kind: 'file', refText: '@file:src/a.ts' }))).toBe('@file:src/a.ts')
})
})
describe('coerceThinkingText', () => {