import { useState, type ComponentProps } from 'react'; import { act, cleanup, fireEvent, render, screen, waitFor, within } from '@testing-library/react'; import { afterEach, beforeEach, expect, it, vi } from 'vitest'; import { CloudComposerAttachments } from '@/pages/CloudAgents/CloudComposerAttachments'; import type { CloudAttachment, CloudFile, CloudHistory } from '../../shared/cloud-agents'; const api = vi.hoisted(() => ({ call: vi.fn(), upload: vi.fn(), download: vi.fn() })); vi.mock('@/lib/cloud-agents-api', () => ({ cloudAgentsApi: api })); const ensureThread = vi.fn(); const onBusy = vi.fn(); const upload: CloudAttachment = { file_id: 'upload-1', file_name: 'notes.txt', file_size: 1024, path: '/notes.md', original_path: '/notes.txt', }; function file(path: string): CloudFile { return { name: path.split('/').at(-1)!, path, directory_path: path.split('/').slice(0, -1).join('/') || '/', is_dir: false, size: 2048 }; } function folder(path: string): CloudFile { return { name: path.split('/').at(-1)!, path, directory_path: path, is_dir: true, size: 0 }; } function delivered(threadId: string, ...paths: string[]): CloudHistory { return { thread_id: threadId, next_offset: null, run: null, messages: [{ id: 1, role: 'assistant', request_id: 'delivery-request', run_id: null, created_at: '', content: paths.map(path => `[${path.split('/').at(-1)}](sandbox:${path})`).join('\n'), }] }; } function deferred() { let resolve!: (value: T) => void; const promise = new Promise(done => { resolve = done; }); return { promise, resolve }; } type HarnessProps = Pick, 'threadId' | 'headerTarget' | 'filesRevision' | 'activeView' | 'deliveryHistory'> & { initialSelected?: string[] }; function Harness({ initialSelected = [], ...props }: HarnessProps) { const [selected, setSelected] = useState(initialSelected); return