import { fireEvent, render, screen } from '@testing-library/react'; import { describe, expect, it, vi } from 'vitest'; import { ExecutionGraphCard } from '@/pages/Chat/ExecutionGraphCard'; import { getToolVisibilityId } from '@/pages/Chat/chat-transcript'; import type { TaskStep } from '@/pages/Chat/task-visualization'; vi.mock('react-i18next', async (importOriginal) => { const actual = await importOriginal(); return { ...actual, useTranslation: () => ({ t: (key: string) => key, }), }; }); describe('ExecutionGraphCard', () => { it('drives the real graph step detail from the shared visibility set', () => { const visibilityId = getToolVisibilityId('msg_assistant', 'tool-read', 0); const onStepExpandedChange = vi.fn(); const step: TaskStep = { id: 'tool-read', visibilityId, label: 'read', status: 'completed', kind: 'tool', detail: '{"file":"README.md"}', depth: 1, }; const { rerender } = render( , ); expect(screen.queryByText(/README\.md/)).not.toBeInTheDocument(); fireEvent.click(screen.getByRole('button', { name: /read/i })); expect(onStepExpandedChange).toHaveBeenCalledWith(visibilityId, true); rerender( , ); expect(screen.getByText(/"file": "README\.md"/)).toBeInTheDocument(); }); it('notifies the parent when an uncontrolled active graph auto-collapses', () => { const onExpandedChange = vi.fn(); const step: TaskStep = { id: 'tool-read', label: 'read', status: 'running', kind: 'tool', detail: '{"file":"README.md"}', depth: 1, }; const { rerender } = render( , ); expect(screen.getByTestId('chat-execution-graph')).toHaveAttribute( 'data-collapsed', 'false', ); rerender( , ); expect(screen.getByTestId('chat-execution-graph')).toHaveAttribute( 'data-collapsed', 'true', ); expect(onExpandedChange).toHaveBeenCalledWith(false); }); it('notifies the parent when a completed uncontrolled graph mounts collapsed', () => { const onExpandedChange = vi.fn(); render( , ); expect(onExpandedChange).toHaveBeenCalledWith(false); }); });