diff --git a/apps/desktop/src/app/chat/composer/attachments.test.tsx b/apps/desktop/src/app/chat/composer/attachments.test.tsx new file mode 100644 index 00000000000..c31e5612f35 --- /dev/null +++ b/apps/desktop/src/app/chat/composer/attachments.test.tsx @@ -0,0 +1,69 @@ +import { cleanup, render, screen } from '@testing-library/react' +import { afterEach, describe, expect, it } from 'vitest' + +import { I18nProvider } from '@/i18n/context' + +import { AttachmentList } from './attachments' +import type { ComposerAttachment } from '@/store/composer' + +function makeAttachment(id: string, label = 'test.pdf'): ComposerAttachment { + return { id, kind: 'file', label } +} + +function renderWithI18n(ui: React.ReactNode) { + return render( + ({}), saveConfig: async () => ({ ok: true }) }}> + {ui} + + ) +} + +describe('AttachmentList', () => { + afterEach(() => { + cleanup() + }) + + it('renders valid attachments', () => { + const attachments = [makeAttachment('a', 'doc.pdf'), makeAttachment('b', 'img.png')] + renderWithI18n() + expect(screen.getByText('doc.pdf')).toBeDefined() + expect(screen.getByText('img.png')).toBeDefined() + }) + + it('renders empty list without error', () => { + renderWithI18n() + const container = screen.getByTestId?.('composer-attachments') ?? document.querySelector('[data-slot="composer-attachments"]') + expect(container).toBeDefined() + }) + + it('does not crash when attachments array contains undefined entries', () => { + // Repro: session switch can leave stale/undefined entries in the + // attachments array, causing a TypeError at attachment.refText. + const attachments = [ + makeAttachment('a', 'good.pdf'), + undefined as unknown as ComposerAttachment, + makeAttachment('b', 'also-good.png') + ] + + expect(() => { + renderWithI18n() + }).not.toThrow() + + // Only valid attachments should render + expect(screen.getByText('good.pdf')).toBeDefined() + expect(screen.getByText('also-good.png')).toBeDefined() + }) + + it('does not crash when attachments array contains null entries', () => { + const attachments = [ + null as unknown as ComposerAttachment, + makeAttachment('a', 'valid.txt') + ] + + expect(() => { + renderWithI18n() + }).not.toThrow() + + expect(screen.getByText('valid.txt')).toBeDefined() + }) +}) diff --git a/apps/desktop/src/app/chat/composer/attachments.tsx b/apps/desktop/src/app/chat/composer/attachments.tsx index 6229c9da8bd..5b353436404 100644 --- a/apps/desktop/src/app/chat/composer/attachments.tsx +++ b/apps/desktop/src/app/chat/composer/attachments.tsx @@ -20,7 +20,7 @@ export function AttachmentList({ }) { return (
- {attachments.map(attachment => ( + {attachments.filter(Boolean).map(attachment => ( ))}