cc-haha/desktop/src/components/chat/AttachmentGallery.test.tsx
程序员阿江(Relakkes) 52b11697e1 feat: make selected context reusable in desktop chat
Workspace and transcript selections now flow into the composer as lightweight references so users can carry exact snippets into the next prompt without file-only workarounds. The prompt formatter keeps workspace and chat excerpts separate, and the composer avoids sending chat snippets as fake file attachments.

Constraint: Selection references must prepare model context without polluting backend file attachment payloads.
Rejected: Reuse file attachments for chat selections | would leak chat:// pseudo paths into file-oriented payloads.
Confidence: high
Scope-risk: moderate
Directive: Keep chat-selection references prompt-only unless the backend gains a first-class chat context attachment type.
Tested: bun run check:desktop
Tested: bun run verify
Tested: agent-browser UI smoke for workspace, user-message, and assistant-message selections
Not-tested: Strict Chrome extension channel; connection timed out, local browser automation covered the flow.
2026-05-13 14:08:12 +08:00

68 lines
1.8 KiB
TypeScript

// @vitest-environment jsdom
import { fireEvent, render } from '@testing-library/react'
import { describe, expect, it, vi } from 'vitest'
import { AttachmentGallery } from './AttachmentGallery'
describe('AttachmentGallery', () => {
it('renders a compact quote preview for selected workspace text', () => {
render(
<AttachmentGallery
variant="composer"
attachments={[{
id: 'selection-1',
type: 'file',
name: 'App.tsx',
path: 'src/App.tsx',
lineStart: 10,
lineEnd: 12,
quote: 'const value = calculate(input)\nreturn value',
}]}
/>,
)
expect(document.body.textContent).toContain('App.tsx:L10-L12')
expect(document.body.textContent).toContain('const value = calculate(input) return value')
})
it('keeps plain file chips on the one-line treatment', () => {
render(
<AttachmentGallery
variant="composer"
attachments={[{
id: 'file-1',
type: 'file',
name: 'README.md',
path: 'README.md',
}]}
/>,
)
expect(document.body.textContent).toContain('README.md')
expect(document.body.textContent).not.toContain(':L')
})
it('removes a quoted workspace attachment by id', () => {
const onRemove = vi.fn()
const view = render(
<AttachmentGallery
variant="composer"
onRemove={onRemove}
attachments={[{
id: 'selection-1',
type: 'file',
name: 'App.tsx',
path: 'src/App.tsx',
lineStart: 10,
quote: 'const value = 1',
}]}
/>,
)
fireEvent.click(view.getByRole('button', { name: 'Remove App.tsx' }))
expect(onRemove).toHaveBeenCalledWith('selection-1')
})
})