import { render, screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { AgentPanel } from '@/components/projects/AgentPanel'; import type { AgentInstance } from '@/components/projects/types'; const mockAgents: AgentInstance[] = [ { id: 'agent-001', agent_type_id: 'type-po', project_id: 'proj-001', name: 'Product Owner', role: 'product_owner', status: 'active', current_task: 'Reviewing user stories', last_activity_at: new Date().toISOString(), spawned_at: '2025-01-15T00:00:00Z', avatar: 'PO', }, { id: 'agent-002', agent_type_id: 'type-be', project_id: 'proj-001', name: 'Backend Engineer', role: 'backend_engineer', status: 'idle', current_task: 'Waiting for review', last_activity_at: new Date().toISOString(), spawned_at: '2025-01-15T00:00:00Z', }, ]; describe('AgentPanel', () => { it('renders agent panel with title', () => { render(); expect(screen.getByText('Active Agents')).toBeInTheDocument(); }); it('shows correct active agent count', () => { render(); expect(screen.getByText('1 of 2 agents working')).toBeInTheDocument(); }); it('renders all agents', () => { render(); expect(screen.getByText('Product Owner')).toBeInTheDocument(); expect(screen.getByText('Backend Engineer')).toBeInTheDocument(); }); it('shows agent current task', () => { render(); expect(screen.getByText('Reviewing user stories')).toBeInTheDocument(); expect(screen.getByText('Waiting for review')).toBeInTheDocument(); }); it('renders empty state when no agents', () => { render(); expect(screen.getByText('No agents assigned to this project')).toBeInTheDocument(); }); it('shows loading skeleton when isLoading is true', () => { const { container } = render(); expect(container.querySelectorAll('.animate-pulse').length).toBeGreaterThan(0); }); it('calls onManageAgents when button is clicked', async () => { const user = userEvent.setup(); const onManageAgents = jest.fn(); render(); await user.click(screen.getByText('Manage Agents')); expect(onManageAgents).toHaveBeenCalledTimes(1); }); it('shows action menu when actions are provided', async () => { const user = userEvent.setup(); const onAgentAction = jest.fn(); render(); const agentItem = screen.getByTestId('agent-item-agent-001'); const menuButton = within(agentItem).getByRole('button', { name: /actions for product owner/i, }); await user.click(menuButton); expect(screen.getByText('View Details')).toBeInTheDocument(); expect(screen.getByText('Pause Agent')).toBeInTheDocument(); expect(screen.getByText('Terminate Agent')).toBeInTheDocument(); }); it('calls onAgentAction with correct params when action is clicked', async () => { const user = userEvent.setup(); const onAgentAction = jest.fn(); render(); const agentItem = screen.getByTestId('agent-item-agent-001'); const menuButton = within(agentItem).getByRole('button', { name: /actions for product owner/i, }); await user.click(menuButton); await user.click(screen.getByText('View Details')); expect(onAgentAction).toHaveBeenCalledWith('agent-001', 'view'); }); it('applies custom className', () => { render(); expect(screen.getByTestId('agent-panel')).toHaveClass('custom-class'); }); it('shows avatar initials for agent', () => { render(); expect(screen.getByText('PO')).toBeInTheDocument(); // Backend Engineer should have generated initials "BE" expect(screen.getByText('BE')).toBeInTheDocument(); }); });